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
next prev 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