gdb: recognize 64 bits Windows executables as Cygwin osabi

Message ID 20200307041742.31158-1-simon.marchi@efficios.com
State Dropped, archived
Headers

Commit Message

Simon Marchi March 7, 2020, 4:17 a.m. UTC
  If I generate two Windows PE executables, one 32 bits and one 64 bits:

    $ x86_64-w64-mingw32-gcc test.c -g3 -O0 -o test_64
    $ i686-w64-mingw32-gcc test.c -g3 -O0 -o test_32
    $ file test_64
    test_64: PE32+ executable (console) x86-64, for MS Windows
    $ file test_32
    test_32: PE32 executable (console) Intel 80386, for MS Windows

When I load the 32 bits binary in my GNU/Linux-hosted GDB, the osabi is
correctly recognized as "Cygwin":

    $ ./gdb --data-directory=data-directory -nx test_32
    (gdb) show osabi
    The current OS ABI is "auto" (currently "Cygwin").

When I load the 64 bits binary in GDB, the osabi is incorrectly
recognized as "GNU/Linux":

    $ ./gdb --data-directory=data-directory -nx test_64
    (gdb) show osabi
    The current OS ABI is "auto" (currently "GNU/Linux").

The 32 bits one gets recognized by the i386_cygwin_osabi_sniffer
function, by its target name:

    if (strcmp (target_name, "pei-i386") == 0)
      return GDB_OSABI_CYGWIN;

The target name for the 64 bits binaries is "pei-x86-64".  It doesn't
get recognized by any osabi sniffer, so GDB falls back on its default
osabi, "GNU/Linux".

This patch adds an osabi sniffer function for the Windows 64 bits
executables in amd64-windows-tdep.c.  With it, the osabi is recognized
as "Cygwin", just like with the 32 bits binary.

I'm not very familiar with the Windows platform, and from what I know
Cygwin and mingw are different things.  A binary compiled with mingw
does not mean it runs on Cygwin.  But from what I understand, the osabi
"Cygwin" in GDB is used for everything Windows.  Not sure that's the
ideal, but that's the way it seems to be right now.

I think it would be good to have a test for this, testing that both 32
bits and 64 bits Windows binaries get correctly recognized, regardless
of the host GDB runs on.  However, I'm not sure how to proceed.

The easiest way would be to generate two small executables and check
them in the repo.  That would allow the test to run on pretty much any
platform GDB is built on.  However, that requires checking in binaries
in the repo, something we don't really do at the moment.

The alternative would be to try to call a mingw/mingw64 compiler
(x86_64-w64-mingw32-gcc in my case), and hope it is installed on the
host.  I find that this greatly reduces the effectiveness of the test,
as it will not be ran by in as many environments.

If someone has an opinion on this or a better idea, I'd like to hear it.

gdb/ChangeLog:

	* amd64-windows-tdep.c (amd64_windows_osabi_sniffer): New
	function.
	(_initialize_amd64_windows_tdep): Register osabi sniffer.
---
 gdb/amd64-windows-tdep.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
  

Comments

Eli Zaretskii March 7, 2020, 8:09 a.m. UTC | #1
> From: Simon Marchi <simon.marchi@efficios.com>
> Cc: Simon Marchi <simon.marchi@efficios.com>
> Date: Fri,  6 Mar 2020 23:17:42 -0500
> 
> When I load the 32 bits binary in my GNU/Linux-hosted GDB, the osabi is
> correctly recognized as "Cygwin":
> 
>     $ ./gdb --data-directory=data-directory -nx test_32
>     (gdb) show osabi
>     The current OS ABI is "auto" (currently "Cygwin").

Why is this correct?  Your debuggee is a MinGW program, not a Cygwin
program.  The OS ABI should say "MinGW" or perhaps even "MS-Windows"
(since MinGW programs are just native Windows executables).

I'm guessing that this is some historical left-over: only Cygwin took
care of returning an OS ABI name at some point in the past, and we
never bothered to augment that for MinGW programs.  I suggest that we
do TRT now, as long as we are on this subject.

The difference between a Cygwin program and a native Windows program
is that the former has a dependency on the Cygwin DLL (or MSYS DLL, if
we want to support MSYS/MSYS2 executables).  Is it possible to make
this distinction where we decide on the OS ABI?

In any case, I see no reason to say that "pei-i386" executables are
necessarily Cygwin programs, the default should be "MS-Windows".

Thanks.
  

Patch

diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index d4d79682dd..2ca979513c 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -1244,10 +1244,24 @@  amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_auto_wide_charset (gdbarch, amd64_windows_auto_wide_charset);
 }
 
+static gdb_osabi
+amd64_windows_osabi_sniffer (bfd *abfd)
+{
+  const char *target_name = bfd_get_target (abfd);
+
+  if (strcmp (target_name, "pei-x86-64") == 0)
+    return GDB_OSABI_CYGWIN;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
 void _initialize_amd64_windows_tdep ();
 void
 _initialize_amd64_windows_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN,
                           amd64_windows_init_abi);
+
+  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
+				  amd64_windows_osabi_sniffer);
 }