Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/4] gdb: distinguish GNU and MSVC flavors of the Windows OS ABI
Date: Tue, 14 Jul 2026 01:45:06 +0100	[thread overview]
Message-ID: <20260714004507.1323332-4-pedro@palves.net> (raw)
In-Reply-To: <20260714004507.1323332-1-pedro@palves.net>

The GNU (MinGW) and MSVC ABIs on Windows are not the same.  They
differ in long double, in the whole C++ ABI, and in other details.
GDB has so far had a single GDB_OSABI_WINDOWS OS ABI covering both.

Unfortunately, it is not possible to reliably distinguish which ABI is
in use from the binary alone -- a PE image doesn't say which
compiler's ABI (or ABIs) it follows.

GDB does have the concept of default OSABI, though, so we can make GDB
pick a different default Windows OSABI depending on which --target GDB
was configured with.  So e.g, a GDB configured with
--target=x86_64-pc-windows-msvc should default to the Windows MSVC
ABI, and GDB configured for MinGW should default to the Windows GNU
ABI.  That's what this patch does.

Introduce two new OS ABIs:

 - GDB_OSABI_WINDOWS_GNU
 - GDB_OSABI_WINDOWS_MSVC

and keep GDB_OSABI_WINDOWS as a generic "Windows, flavor
undetermined".

The osabi sniffers and gdbserver's target description continue
reporting the generic value.  GDB resolves the generic Windows value
to a concrete flavor, after consulting all the OS ABI sources.

In configure.tgt, we now map "mingw" to GDB_OSABI_WINDOWS_GNU and the
"windows-msvc" to GDB_OSABI_WINDOWS_MSVC.  A bare "windows" OS in the
triplet, with no environment, maps to MSVC ABI, same as what LLVM
does.

An explicit GNU environment in the triplet (like e.g.,
x86_64-pc-windows-gnu) maps to GDB_OSABI_WINDOWS_GNU.  Note that
config.sub does not accept a "windows-gnu" triplet today.  This
triplet is used by MinGW ABI clang and Rust, though, so I still think
we should add it now so that the osabi mapping stays correct if
windows-gnu is ever wired up throughout the tree.

"set osabi" gains the two new "Windows-GNU" and "Windows-MSVC" values.
The generic "Windows" value remains selectable too -- it is registered
as a name without a handler via the new gdbarch_add_osabi_name
function, since it is never the final ABI of a gdbarch, only a request
to let GDB pick the flavor.  Selecting it goes through the same
resolution as auto-detection.

Because selecting the generic "Windows" resolves to a different OS ABI
than the one named, "show osabi" reports both the selected value and
the one it resolved to, e.g.:

 (gdb) set osabi Windows
 (gdb) show osabi
 The current OS ABI is "Windows" (resolved to "Windows-GNU").
 The default OS ABI is "GNU/Linux".

This is similar to "set osabi auto", but uses "resolved to" rather
than "currently" as the latter would read a bit awkward and unclear with the repeated "current", as in:

 (current OS ABI is "foo" (currently "bar").
  ^^^^^^^                  ^^^^^^^^^

Change-Id: Ic20ce4085052bdb9b78d28d399d6907f6fced0c6
---
 gdb/NEWS                   | 16 ++++++++++++++++
 gdb/aarch64-windows-tdep.c |  5 ++++-
 gdb/amd64-windows-tdep.c   |  6 +++++-
 gdb/arch-utils.c           | 18 ++++++++++++++++++
 gdb/configure.tgt          |  8 ++++++--
 gdb/doc/gdb.texinfo        | 15 +++++++++++++++
 gdb/i386-windows-tdep.c    |  6 +++++-
 gdb/osabi.c                | 32 +++++++++++++++++++++++++++-----
 gdb/osabi.h                |  8 ++++++++
 gdb/windows-tdep.h         |  5 +++--
 gdbsupport/osabi.def       |  2 ++
 11 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index ec9b5a33787..cf3948f87e4 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -103,6 +103,16 @@
   everywhere GDB shows a filename/dirname: source filenames,
   executable filename, shared libraries, the cd/pwd commands, etc.
 
+* GDB now distinguishes between the GNU (MinGW) and MSVC Windows ABIs.
+
+  The "set osabi" command accepts two new values, "Windows-GNU" and
+  "Windows-MSVC".  The existing "Windows" value continues to work and
+  now means "let GDB pick the flavor": GDB uses the configured default
+  OS ABI (from --target) when that is a Windows flavor, and otherwise
+  assumes the GNU flavor.  E.g., --target=x86_64-pc-windows-msvc
+  defaults to the MSVC ABI, and --target=x86_64-w64-mingw32 defaults
+  to GNU ABI.  See "New targets" entry below.
+
 * GDB now supports libipt v2.2 events originating from Event Tracing (set
   record btrace pt event-tracing on) on a FRED-enabled system and from
   Trigger Tracing.
@@ -128,6 +138,12 @@ GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux*
 
 AArch64 MinGW                   aarch64-*-mingw*
 
+i386 Windows/MSVC               i[34567]86-*-windows-msvc
+
+amd64 Windows/MSVC              x86_64-*-windows-msvc
+
+AArch64 Windows/MSVC            aarch64-*-windows-msvc
+
 * Deprecated targets
 
 GNU/Linux/S390 32-bit		s390-*-*
diff --git a/gdb/aarch64-windows-tdep.c b/gdb/aarch64-windows-tdep.c
index 7932f27b83b..647ee500dd0 100644
--- a/gdb/aarch64-windows-tdep.c
+++ b/gdb/aarch64-windows-tdep.c
@@ -62,8 +62,11 @@ aarch64_windows_osabi_sniffer (bfd *abfd)
 
 INIT_GDB_FILE (aarch64_windows_tdep)
 {
-  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_WINDOWS,
+  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_WINDOWS_GNU,
 			  aarch64_windows_init_abi);
+  gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_WINDOWS_MSVC,
+			  aarch64_windows_init_abi);
+  gdbarch_add_osabi_name (GDB_OSABI_WINDOWS);
 
   gdbarch_register_osabi_sniffer (bfd_arch_aarch64, bfd_target_coff_flavour,
 				  aarch64_windows_osabi_sniffer);
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index 85f7ac51a4f..68dd2f354fe 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -1392,8 +1392,12 @@ amd64_cygwin_core_osabi_sniffer (bfd *abfd)
 
 INIT_GDB_FILE (amd64_windows_tdep)
 {
-  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS,
+  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS_GNU,
 			  amd64_windows_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS_MSVC,
+			  amd64_windows_init_abi);
+  gdbarch_add_osabi_name (GDB_OSABI_WINDOWS);
+
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN,
 			  amd64_cygwin_init_abi);
 
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index e959788bd3b..473a352e781 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -825,6 +825,24 @@ gdbarch_info_fill (struct gdbarch_info *info)
   if (info->osabi == GDB_OSABI_UNKNOWN)
     info->osabi = GDB_OSABI_DEFAULT;
 #endif
+
+  /* A generic "Windows" OS ABI means a PE binary whose flavor --
+     GNU (MinGW) or MSVC -- could not be determined.  The osabi
+     sniffers and gdbserver's target description both report the
+     generic "Windows" OS ABI, because neither can tell the two
+     flavors apart from the binary alone.  Resolve it here to a
+     concrete flavor: use the configured default if that is itself a
+     Windows flavor, otherwise assume GNU.  */
+  if (info->osabi == GDB_OSABI_WINDOWS)
+    {
+      info->osabi = GDB_OSABI_WINDOWS_GNU;
+#ifdef GDB_OSABI_DEFAULT
+      if (GDB_OSABI_DEFAULT == GDB_OSABI_WINDOWS_GNU
+	  || GDB_OSABI_DEFAULT == GDB_OSABI_WINDOWS_MSVC)
+	info->osabi = GDB_OSABI_DEFAULT;
+#endif
+    }
+
   /* If we still don't know which osabi to pick, pick none.  */
   if (info->osabi == GDB_OSABI_UNKNOWN)
     info->osabi = GDB_OSABI_NONE;
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index f473f67d8bd..2f164405c16 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -819,10 +819,14 @@ case "${targ}" in
 m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;;
 *-*-openbsd*)	gdb_osabi=GDB_OSABI_OPENBSD ;;
 *-*-solaris*)	gdb_osabi=GDB_OSABI_SOLARIS ;;
+# Match the Windows OS ABIs before the non-GNU-kernel guard below,
+# which would otherwise swallow the "-gnu" of a windows-gnu (MinGW)
+# triplet and leave gdb_osabi unset.
+*-*-mingw32ce*)	gdb_osabi=GDB_OSABI_WINCE ;;
+*-*-mingw* | *-*-windows*gnu*)	gdb_osabi=GDB_OSABI_WINDOWS_GNU ;;
+*-*-windows*)	gdb_osabi=GDB_OSABI_WINDOWS_MSVC ;;
 *-*-*-gnu*)	;; # prevent non-GNU kernels to match the Hurd rule below
 *-*-gnu*)	gdb_osabi=GDB_OSABI_HURD ;;
-*-*-mingw32ce*)	gdb_osabi=GDB_OSABI_WINCE ;;
-*-*-mingw* | *-*-windows*)	gdb_osabi=GDB_OSABI_WINDOWS ;;
 *-*-cygwin*)	gdb_osabi=GDB_OSABI_CYGWIN ;;
 *-*-dicos*)	gdb_osabi=GDB_OSABI_DICOS ;;
 powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a698b2b8451..0ca1b37fe57 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -28680,6 +28680,15 @@ When @value{GDBN} is debugging the AArch64 architecture, it provides a
 @code{longjmp} when debugging binaries that use the @sc{newlib} C library.
 The ``Newlib'' OS ABI can be selected by @code{set osabi Newlib}.
 
+On Windows, the GNU (MinGW) and MSVC toolchains use different ABIs.
+For example, they disagree on the size of @code{long double}.
+@value{GDBN} provides a separate OS ABI for each: ``Windows-GNU'' and
+``Windows-MSVC''.  A generic ``Windows'' OS ABI is also available.  It
+does not select a flavor directly, but asks @value{GDBN} to pick one:
+@value{GDBN} uses the OS ABI it was configured with by default (from
+the @code{--target} configure option) when that is a Windows flavor,
+and otherwise assumes the GNU flavor.
+
 @table @code
 @item show osabi
 Show the OS ABI currently in use.
@@ -49441,6 +49450,12 @@ An @samp{<osabi>} element has this form:
 @var{abi-name} is an OS ABI name from the same selection accepted by
 @w{@code{set osabi}} (@pxref{ABI, ,Configuring the Current ABI}).
 
+For Windows targets, a stub should report the generic ``Windows'' OS
+ABI rather than ``Windows-GNU'' or ``Windows-MSVC'', as the running
+program does not record which toolchain's ABI it follows.
+@value{GDBN} resolves the generic name to a flavor itself (@pxref{ABI,
+,Configuring the Current ABI}).
+
 @subsection Compatible Architecture
 @cindex @code{<compatible>}
 
diff --git a/gdb/i386-windows-tdep.c b/gdb/i386-windows-tdep.c
index b66483c4b96..b8db0b9d5fb 100644
--- a/gdb/i386-windows-tdep.c
+++ b/gdb/i386-windows-tdep.c
@@ -230,8 +230,12 @@ INIT_GDB_FILE (i386_windows_tdep)
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
 				  i386_cygwin_core_osabi_sniffer);
 
-  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
+  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS_GNU,
 			  i386_windows_init_abi);
+  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS_MSVC,
+			  i386_windows_init_abi);
+  gdbarch_add_osabi_name (GDB_OSABI_WINDOWS);
+
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
 			  i386_cygwin_init_abi);
 }
diff --git a/gdb/osabi.c b/gdb/osabi.c
index 49f618610b0..0ebfe07951e 100644
--- a/gdb/osabi.c
+++ b/gdb/osabi.c
@@ -62,7 +62,6 @@ gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
 {
   struct gdb_osabi_handler **handler_p;
   const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine);
-  const char **name_ptr;
 
   /* Registering an OS ABI handler for "unknown" is not allowed.  */
   if (osabi == GDB_OSABI_UNKNOWN)
@@ -101,8 +100,17 @@ gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
   (*handler_p)->osabi = osabi;
   (*handler_p)->init_osabi = init_osabi;
 
-  /* Add this OS ABI to the list of enum values for "set osabi", if it isn't
-     already there.  */
+  /* Add this OS ABI to the list of enum values for "set osabi".  */
+  gdbarch_add_osabi_name (osabi);
+}
+
+/* See osabi.h.  */
+
+void
+gdbarch_add_osabi_name (enum gdb_osabi osabi)
+{
+  const char **name_ptr;
+
   for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++)
     {
       if (*name_ptr == gdbarch_osabi_name (osabi))
@@ -601,8 +609,22 @@ show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c,
 		  "(currently \"%s\").\n"),
 		gdbarch_osabi_name (gdbarch_osabi (get_current_arch ())));
   else
-    gdb_printf (file, _("The current OS ABI is \"%s\".\n"),
-		gdbarch_osabi_name (user_selected_osabi));
+    {
+      /* The OS ABI in effect may differ from the one the user
+	 selected: a generic OS ABI such as "Windows" is resolved to a
+	 concrete one (a Windows flavor) when the gdbarch is
+	 built.  */
+      enum gdb_osabi effective = gdbarch_osabi (get_current_arch ());
+
+      if (effective != user_selected_osabi)
+	gdb_printf (file,
+		    _("The current OS ABI is \"%s\" (resolved to \"%s\").\n"),
+		    gdbarch_osabi_name (user_selected_osabi),
+		    gdbarch_osabi_name (effective));
+      else
+	gdb_printf (file, _("The current OS ABI is \"%s\".\n"),
+		    gdbarch_osabi_name (user_selected_osabi));
+    }
 
   if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
     gdb_printf (file, _("The default OS ABI is \"%s\".\n"),
diff --git a/gdb/osabi.h b/gdb/osabi.h
index 9c9886aba7a..a96dbd96531 100644
--- a/gdb/osabi.h
+++ b/gdb/osabi.h
@@ -38,6 +38,14 @@ void gdbarch_register_osabi (enum bfd_architecture, unsigned long,
 			     void (*)(struct gdbarch_info,
 				      struct gdbarch *));
 
+/* Make OSABI selectable via the "set osabi" command without
+   registering a handler for it.  This is for an OS ABI that is never
+   the final ABI of a gdbarch, but that a user may still want to
+   select -- it is resolved to a concrete ABI elsewhere.  The generic
+   "Windows" OS ABI is one example: it stands for "let GDB pick the
+   GNU or MSVC flavor".  */
+void gdbarch_add_osabi_name (enum gdb_osabi osabi);
+
 /* Lookup the OS ABI corresponding to the specified BFD.  */
 enum gdb_osabi gdbarch_lookup_osabi (bfd *);
 
diff --git a/gdb/windows-tdep.h b/gdb/windows-tdep.h
index 235528ee30b..7cbc6ea9334 100644
--- a/gdb/windows-tdep.h
+++ b/gdb/windows-tdep.h
@@ -41,8 +41,9 @@ extern ULONGEST windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
 extern std::string windows_core_pid_to_str (struct gdbarch *gdbarch,
 					    ptid_t ptid);
 
-/* To be called from the various GDB_OSABI_WINDOWS handlers for the
-   various Windows architectures and machine types.  */
+/* To be called from the various GDB_OSABI_WINDOWS_GNU and
+   GDB_OSABI_WINDOWS_MSVC handlers for the various Windows
+   architectures and machine types.  */
 
 extern void windows_init_abi (struct gdbarch_info info,
 			      struct gdbarch *gdbarch);
diff --git a/gdbsupport/osabi.def b/gdbsupport/osabi.def
index 230c21f0236..69732b90f43 100644
--- a/gdbsupport/osabi.def
+++ b/gdbsupport/osabi.def
@@ -45,6 +45,8 @@ GDB_OSABI_DEF (WINCE, "WindowsCE", nullptr)
 GDB_OSABI_DEF (GO32, "DJGPP", nullptr)
 GDB_OSABI_DEF (CYGWIN, "Cygwin", nullptr)
 GDB_OSABI_DEF (WINDOWS, "Windows", nullptr)
+GDB_OSABI_DEF (WINDOWS_GNU, "Windows-GNU", nullptr)
+GDB_OSABI_DEF (WINDOWS_MSVC, "Windows-MSVC", nullptr)
 GDB_OSABI_DEF (AIX, "AIX", nullptr)
 GDB_OSABI_DEF (DICOS, "DICOS", nullptr)
 GDB_OSABI_DEF (DARWIN, "Darwin", nullptr)
-- 
2.54.0


  parent reply	other threads:[~2026-07-14  0:47 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  0:45 [PATCH 0/4] Support the Windows/MSVC target in GDB Pedro Alves
2026-07-14  0:45 ` [PATCH 1/4] gdb: recognize *-*-windows* Windows targets Pedro Alves
2026-07-14  0:45 ` [PATCH 2/4] gdb: treat Windows host + Windows target as native Pedro Alves
2026-07-14  0:45 ` Pedro Alves [this message]
2026-07-14 11:57   ` [PATCH 3/4] gdb: distinguish GNU and MSVC flavors of the Windows OS ABI Eli Zaretskii
2026-07-14 22:15     ` Pedro Alves
2026-07-15  1:21       ` Simon Marchi
2026-07-15 11:18         ` Pedro Alves
2026-07-15 13:13           ` Simon Marchi
2026-07-15 14:10             ` Pedro Alves
2026-07-15 15:51               ` Simon Marchi
2026-07-15 11:43       ` Eli Zaretskii
2026-07-14  0:45 ` [PATCH 4/4] gdb: MSVC "long double" is a 64-bit double Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260714004507.1323332-4-pedro@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox