gdb: stop using host-dependent signal numbers in windows-tdep.c
authorSimon Marchi <simon.marchi@polymtl.ca>
Wed, 8 Apr 2020 18:05:54 +0000 (14:05 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Wed, 8 Apr 2020 18:05:54 +0000 (14:05 -0400)
The signal enumeration in windows-tdep.c is defined differently whether
it is compiled on Cygwin or not.  This is problematic, since the code in
tdep files is not supposed to be influenced by the host platform (the
platform GDB itself runs on).

This makes a difference in windows_gdb_signal_to_target.  An obvious
example of clash is SIGABRT.  Let's pretend we are cross-debugging a
Cygwin process from a MinGW (non-Cygwin Windows) GDB.  If GDB needs to
translate the gdb signal number GDB_SIGNAL_ABRT into a target
equivalent, it would obtain the MinGW number (22), despite the target
being a Cygwin process.  Conversely, if debugging a MinGW process from a
Cygwin-hosted GDB, GDB_SIGNAL_ABRT would be converted to a Cygwin signal
number (6) despite the target being a MinGW process.  This is wrong,
since we want the result to depend on the target's platform, not GDB's
platform.

This known flaw was accepted because at the time we had a single OS ABI
(called Cygwin) for all Windows binaries (Cygwin ones and non-Cygwin
ones).  This limitation is now lifted, as we now have separate Windows
and Cygwin OS ABIs.  This means we are able to detect at runtime whether
the binary we are debugging is a Cygwin one or non-Cygwin one.

This patch splits the signal enum in two, one for the MinGW flavors and
one for Cygwin, removing all the ifdefs that made it depend on the host
platform.  It then makes two separate gdb_signal_to_target gdbarch
methods, that are used according to the OS ABI selected at runtime.

There is a bit of re-shuffling needed in how the gdbarch'es are
initialized, but nothing major.

gdb/ChangeLog:

* windows-tdep.h (windows_init_abi): Add comment.
(cygwin_init_abi): New declaration.
* windows-tdep.c: Split signal enumeration in two, one for
Windows and one for Cygwin.
(windows_gdb_signal_to_target): Only deal with signal of the
Windows OS ABI.
(cygwin_gdb_signal_to_target): New function.
(windows_init_abi): Rename to windows_init_abi_common, don't set
gdb_signal_to_target gdbarch method.  Add new new function with
this name.
(cygwin_init_abi): New function.
* amd64-windows-tdep.c (amd64_windows_init_abi_common): Add
comment.  Don't call windows_init_abi.
(amd64_windows_init_abi): Add comment, call windows_init_abi.
(amd64_cygwin_init_abi): Add comment, call cygwin_init_abi.
* i386-windows-tdep.c (i386_windows_init_abi): Rename to
i386_windows_init_abi_common, don't call windows_init_abi.  Add
a new function of this name.
(i386_cygwin_init_abi): New function.
(_initialize_i386_windows_tdep): Bind i386_cygwin_init_abi to
OS ABI Cygwin.

gdb/ChangeLog
gdb/amd64-windows-tdep.c
gdb/i386-windows-tdep.c
gdb/windows-tdep.c
gdb/windows-tdep.h

index 7ea85799211ab92f39cbd6cdc712757ebd876a47..6d958a2d9b8020a93c924e44381b336e788c3544 100644 (file)
@@ -1,3 +1,27 @@
+2020-04-08  Simon Marchi  <simon.marchi@polymtl.ca>
+
+       * windows-tdep.h (windows_init_abi): Add comment.
+       (cygwin_init_abi): New declaration.
+       * windows-tdep.c: Split signal enumeration in two, one for
+       Windows and one for Cygwin.
+       (windows_gdb_signal_to_target): Only deal with signal of the
+       Windows OS ABI.
+       (cygwin_gdb_signal_to_target): New function.
+       (windows_init_abi): Rename to windows_init_abi_common, don't set
+       gdb_signal_to_target gdbarch method.  Add new new function with
+       this name.
+       (cygwin_init_abi): New function.
+       * amd64-windows-tdep.c (amd64_windows_init_abi_common): Add
+       comment.  Don't call windows_init_abi.
+       (amd64_windows_init_abi): Add comment, call windows_init_abi.
+       (amd64_cygwin_init_abi): Add comment, call cygwin_init_abi.
+       * i386-windows-tdep.c (i386_windows_init_abi): Rename to
+       i386_windows_init_abi_common, don't call windows_init_abi.  Add
+       a new function of this name.
+       (i386_cygwin_init_abi): New function.
+       (_initialize_i386_windows_tdep): Bind i386_cygwin_init_abi to
+       OS ABI Cygwin.
+
 2020-04-08  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * dwarf2/read.c (read_gdb_index_from_buffer): Remove objfile
index 6d5076d1c4371becf4b122a5393ede780cd0f37a..740152b7de8e170fac46fc280a66364908d912c1 100644 (file)
@@ -1208,6 +1208,8 @@ amd64_windows_auto_wide_charset (void)
   return "UTF-16";
 }
 
+/* Common parts for gdbarch initialization for Windows and Cygwin on AMD64.  */
+
 static void
 amd64_windows_init_abi_common (gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -1227,8 +1229,6 @@ amd64_windows_init_abi_common (gdbarch_info info, struct gdbarch *gdbarch)
   amd64_init_abi (info, gdbarch,
                  amd64_target_description (X86_XSTATE_SSE_MASK, false));
 
-  windows_init_abi (info, gdbarch);
-
   /* Function calls.  */
   set_gdbarch_push_dummy_call (gdbarch, amd64_windows_push_dummy_call);
   set_gdbarch_return_value (gdbarch, amd64_windows_return_value);
@@ -1241,19 +1241,25 @@ amd64_windows_init_abi_common (gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_auto_wide_charset (gdbarch, amd64_windows_auto_wide_charset);
 }
 
+/* gdbarch initialization for Windows on AMD64.  */
+
 static void
 amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   amd64_windows_init_abi_common (info, gdbarch);
+  windows_init_abi (info, gdbarch);
 
   /* On Windows, "long"s are only 32bit.  */
   set_gdbarch_long_bit (gdbarch, 32);
 }
 
+/* gdbarch initialization for Cygwin on AMD64.  */
+
 static void
 amd64_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   amd64_windows_init_abi_common (info, gdbarch);
+  cygwin_init_abi (info, gdbarch);
 }
 
 static gdb_osabi
index b26731c6bf2895985284d126f37e41177e8e5c8f..3a07c862f23331a4206cebc575b55db270cb4f75 100644 (file)
@@ -200,13 +200,13 @@ i386_windows_auto_wide_charset (void)
   return "UTF-16";
 }
 
+/* Common parts for gdbarch initialization for Windows and Cygwin on i386.  */
+
 static void
-i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+i386_windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  windows_init_abi (info, gdbarch);
-
   set_gdbarch_skip_trampoline_code (gdbarch, i386_windows_skip_trampoline_code);
 
   set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
@@ -227,6 +227,24 @@ i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_auto_wide_charset (gdbarch, i386_windows_auto_wide_charset);
 }
 
+/* gdbarch initialization for Windows on i386.  */
+
+static void
+i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  i386_windows_init_abi_common (info, gdbarch);
+  windows_init_abi (info, gdbarch);
+}
+
+/* gdbarch initialization for Cygwin on i386.  */
+
+static void
+i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  i386_windows_init_abi_common (info, gdbarch);
+  cygwin_init_abi (info, gdbarch);
+}
+
 static gdb_osabi
 i386_windows_osabi_sniffer (bfd *abfd)
 {
@@ -270,9 +288,8 @@ _initialize_i386_windows_tdep ()
   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
                                   i386_cygwin_core_osabi_sniffer);
 
-  /* The Windows and Cygwin OS ABIs are currently equivalent on i386.  */
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
                           i386_windows_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
-                          i386_windows_init_abi);
+                         i386_cygwin_init_abi);
 }
index 662a46fe1d702ed4bace839c7bfa33567db8b89f..d1894ca08884505ea8bdba89fcd07fe0322eea8d 100644 (file)
 #define CYGWIN_DLL_NAME "cygwin1.dll"
 
 /* Windows signal numbers differ between MinGW flavors and between
-   those and Cygwin.  The below enumeration was gleaned from the
-   respective headers; the ones marked with MinGW64/Cygwin are defined
-   only by MinGW64 and Cygwin, not by mingw.org's MinGW.  FIXME: We
-   should really have distinct MinGW vs Cygwin OSABIs, and two
-   separate enums, selected at runtime.  */
+   those and Cygwin.  The below enumerations were gleaned from the
+   respective headers.  */
+
+/* Signal numbers for the various MinGW flavors.  The ones marked with
+   MinGW-w64 are defined by MinGW-w64, not by mingw.org's MinGW.  */
 
 enum
-  {
-   WINDOWS_SIGHUP = 1, /* MinGW64/Cygwin */
-   WINDOWS_SIGINT = 2,
-   WINDOWS_SIGQUIT = 3,        /* MinGW64/Cygwin */
-   WINDOWS_SIGILL = 4,
-   WINDOWS_SIGTRAP = 5,        /* MinGW64/Cygwin */
-#ifdef __CYGWIN__
-   WINDOWS_SIGABRT = 6,
-#else
-   WINDOWS_SIGIOT = 6, /* MinGW64 */
-#endif
-   WINDOWS_SIGEMT = 7, /* MinGW64/Cygwin */
-   WINDOWS_SIGFPE = 8,
-   WINDOWS_SIGKILL = 9,        /* MinGW64/Cygwin */
-   WINDOWS_SIGBUS = 10,        /* MinGW64/Cygwin */
-   WINDOWS_SIGSEGV = 11,
-   WINDOWS_SIGSYS = 12,        /* MinGW64/Cygwin */
-   WINDOWS_SIGPIPE = 13,/* MinGW64/Cygwin */
-   WINDOWS_SIGALRM = 14,/* MinGW64/Cygwin */
-   WINDOWS_SIGTERM = 15,
-#ifdef __CYGWIN__
-   WINDOWS_SIGURG = 16,
-   WINDOWS_SIGSTOP = 17,
-   WINDOWS_SIGTSTP = 18,
-   WINDOWS_SIGCONT = 19,
-   WINDOWS_SIGCHLD = 20,
-   WINDOWS_SIGTTIN = 21,
-   WINDOWS_SIGTTOU = 22,
-   WINDOWS_SIGIO = 23,
-   WINDOWS_SIGXCPU = 24,
-   WINDOWS_SIGXFSZ = 25,
-   WINDOWS_SIGVTALRM = 26,
-   WINDOWS_SIGPROF = 27,
-   WINDOWS_SIGWINCH = 28,
-   WINDOWS_SIGLOST = 29,
-   WINDOWS_SIGUSR1 = 30,
-   WINDOWS_SIGUSR2 = 31
-#else
-   WINDOWS_SIGBREAK = 21,
-   WINDOWS_SIGABRT = 22
-#endif
-  };
+{
+  WINDOWS_SIGHUP = 1,  /* MinGW-w64 */
+  WINDOWS_SIGINT = 2,
+  WINDOWS_SIGQUIT = 3, /* MinGW-w64 */
+  WINDOWS_SIGILL = 4,
+  WINDOWS_SIGTRAP = 5, /* MinGW-w64 */
+  WINDOWS_SIGIOT = 6,  /* MinGW-w64 */
+  WINDOWS_SIGEMT = 7,  /* MinGW-w64 */
+  WINDOWS_SIGFPE = 8,
+  WINDOWS_SIGKILL = 9, /* MinGW-w64 */
+  WINDOWS_SIGBUS = 10, /* MinGW-w64 */
+  WINDOWS_SIGSEGV = 11,
+  WINDOWS_SIGSYS = 12, /* MinGW-w64 */
+  WINDOWS_SIGPIPE = 13,        /* MinGW-w64 */
+  WINDOWS_SIGALRM = 14,        /* MinGW-w64 */
+  WINDOWS_SIGTERM = 15,
+  WINDOWS_SIGBREAK = 21,
+  WINDOWS_SIGABRT = 22,
+};
+
+/* Signal numbers for Cygwin.  */
+
+enum
+{
+  CYGWIN_SIGHUP = 1,
+  CYGWIN_SIGINT = 2,
+  CYGWIN_SIGQUIT = 3,
+  CYGWIN_SIGILL = 4,
+  CYGWIN_SIGTRAP = 5,
+  CYGWIN_SIGABRT = 6,
+  CYGWIN_SIGEMT = 7,
+  CYGWIN_SIGFPE = 8,
+  CYGWIN_SIGKILL = 9,
+  CYGWIN_SIGBUS = 10,
+  CYGWIN_SIGSEGV = 11,
+  CYGWIN_SIGSYS = 12,
+  CYGWIN_SIGPIPE = 13,
+  CYGWIN_SIGALRM = 14,
+  CYGWIN_SIGTERM = 15,
+  CYGWIN_SIGURG = 16,
+  CYGWIN_SIGSTOP = 17,
+  CYGWIN_SIGTSTP = 18,
+  CYGWIN_SIGCONT = 19,
+  CYGWIN_SIGCHLD = 20,
+  CYGWIN_SIGTTIN = 21,
+  CYGWIN_SIGTTOU = 22,
+  CYGWIN_SIGIO = 23,
+  CYGWIN_SIGXCPU = 24,
+  CYGWIN_SIGXFSZ = 25,
+  CYGWIN_SIGVTALRM = 26,
+  CYGWIN_SIGPROF = 27,
+  CYGWIN_SIGWINCH = 28,
+  CYGWIN_SIGLOST = 29,
+  CYGWIN_SIGUSR1 = 30,
+  CYGWIN_SIGUSR2 = 31,
+};
 
 struct cmd_list_element *info_w32_cmdlist;
 
@@ -607,7 +621,7 @@ init_w32_command_list (void)
     }
 }
 
-/* Implementation of `gdbarch_gdb_signal_to_target'.  */
+/* Implementation of `gdbarch_gdb_signal_to_target' for Windows.  */
 
 static int
 windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
@@ -646,40 +660,81 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
       return WINDOWS_SIGALRM;
     case GDB_SIGNAL_TERM:
       return WINDOWS_SIGTERM;
-#ifdef __CYGWIN__
+    }
+  return -1;
+}
+
+/* Implementation of `gdbarch_gdb_signal_to_target' for Cygwin.  */
+
+static int
+cygwin_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
+{
+  switch (signal)
+    {
+    case GDB_SIGNAL_0:
+      return 0;
+    case GDB_SIGNAL_HUP:
+      return CYGWIN_SIGHUP;
+    case GDB_SIGNAL_INT:
+      return CYGWIN_SIGINT;
+    case GDB_SIGNAL_QUIT:
+      return CYGWIN_SIGQUIT;
+    case GDB_SIGNAL_ILL:
+      return CYGWIN_SIGILL;
+    case GDB_SIGNAL_TRAP:
+      return CYGWIN_SIGTRAP;
+    case GDB_SIGNAL_ABRT:
+      return CYGWIN_SIGABRT;
+    case GDB_SIGNAL_EMT:
+      return CYGWIN_SIGEMT;
+    case GDB_SIGNAL_FPE:
+      return CYGWIN_SIGFPE;
+    case GDB_SIGNAL_KILL:
+      return CYGWIN_SIGKILL;
+    case GDB_SIGNAL_BUS:
+      return CYGWIN_SIGBUS;
+    case GDB_SIGNAL_SEGV:
+      return CYGWIN_SIGSEGV;
+    case GDB_SIGNAL_SYS:
+      return CYGWIN_SIGSYS;
+    case GDB_SIGNAL_PIPE:
+      return CYGWIN_SIGPIPE;
+    case GDB_SIGNAL_ALRM:
+      return CYGWIN_SIGALRM;
+    case GDB_SIGNAL_TERM:
+      return CYGWIN_SIGTERM;
     case GDB_SIGNAL_URG:
-      return WINDOWS_SIGURG;
+      return CYGWIN_SIGURG;
     case GDB_SIGNAL_STOP:
-      return WINDOWS_SIGSTOP;
+      return CYGWIN_SIGSTOP;
     case GDB_SIGNAL_TSTP:
-      return WINDOWS_SIGTSTP;
+      return CYGWIN_SIGTSTP;
     case GDB_SIGNAL_CONT:
-      return WINDOWS_SIGCONT;
+      return CYGWIN_SIGCONT;
     case GDB_SIGNAL_CHLD:
-      return WINDOWS_SIGCHLD;
+      return CYGWIN_SIGCHLD;
     case GDB_SIGNAL_TTIN:
-      return WINDOWS_SIGTTIN;
+      return CYGWIN_SIGTTIN;
     case GDB_SIGNAL_TTOU:
-      return WINDOWS_SIGTTOU;
+      return CYGWIN_SIGTTOU;
     case GDB_SIGNAL_IO:
-      return WINDOWS_SIGIO;
+      return CYGWIN_SIGIO;
     case GDB_SIGNAL_XCPU:
-      return WINDOWS_SIGXCPU;
+      return CYGWIN_SIGXCPU;
     case GDB_SIGNAL_XFSZ:
-      return WINDOWS_SIGXFSZ;
+      return CYGWIN_SIGXFSZ;
     case GDB_SIGNAL_VTALRM:
-      return WINDOWS_SIGVTALRM;
+      return CYGWIN_SIGVTALRM;
     case GDB_SIGNAL_PROF:
-      return WINDOWS_SIGPROF;
+      return CYGWIN_SIGPROF;
     case GDB_SIGNAL_WINCH:
-      return WINDOWS_SIGWINCH;
+      return CYGWIN_SIGWINCH;
     case GDB_SIGNAL_PWR:
-      return WINDOWS_SIGLOST;
+      return CYGWIN_SIGLOST;
     case GDB_SIGNAL_USR1:
-      return WINDOWS_SIGUSR1;
+      return CYGWIN_SIGUSR1;
     case GDB_SIGNAL_USR2:
-      return WINDOWS_SIGUSR2;
-#endif /* __CYGWIN__ */
+      return CYGWIN_SIGUSR2;
     }
   return -1;
 }
@@ -865,11 +920,11 @@ windows_solib_create_inferior_hook (int from_tty)
 
 static struct target_so_ops windows_so_ops;
 
-/* To be called from the various GDB_OSABI_CYGWIN handlers for the
-   various Windows architectures and machine types.  */
+/* Common parts for gdbarch initialization for the Windows and Cygwin OS
+   ABIs.  */
 
-void
-windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+static void
+windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   set_gdbarch_wchar_bit (gdbarch, 16);
   set_gdbarch_wchar_signed (gdbarch, 0);
@@ -881,8 +936,6 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_iterate_over_objfiles_in_search_order
     (gdbarch, windows_iterate_over_objfiles_in_search_order);
 
-  set_gdbarch_gdb_signal_to_target (gdbarch, windows_gdb_signal_to_target);
-
   windows_so_ops = solib_target_so_ops;
   windows_so_ops.solib_create_inferior_hook
     = windows_solib_create_inferior_hook;
@@ -891,6 +944,23 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
 }
 
+/* See windows-tdep.h.  */
+void
+windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  windows_init_abi_common (info, gdbarch);
+  set_gdbarch_gdb_signal_to_target (gdbarch, windows_gdb_signal_to_target);
+}
+
+/* See windows-tdep.h.  */
+
+void
+cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  windows_init_abi_common (info, gdbarch);
+  set_gdbarch_gdb_signal_to_target (gdbarch, cygwin_gdb_signal_to_target);
+}
+
 /* Implementation of `tlb' variable.  */
 
 static const struct internalvar_funcs tlb_funcs =
index f2dc4260469dda5f229b314abb4445a270a033db..cd7717bd9174576d8f6c6a477f1b1c3a33cb5f31 100644 (file)
@@ -31,9 +31,18 @@ extern void windows_xfer_shared_library (const char* so_name,
                                         struct gdbarch *gdbarch,
                                         struct obstack *obstack);
 
+/* To be called from the various GDB_OSABI_WINDOWS handlers for the
+   various Windows architectures and machine types.  */
+
 extern void windows_init_abi (struct gdbarch_info info,
                              struct gdbarch *gdbarch);
 
+/* To be called from the various GDB_OSABI_CYGWIN handlers for the
+   various Windows architectures and machine types.  */
+
+extern void cygwin_init_abi (struct gdbarch_info info,
+                            struct gdbarch *gdbarch);
+
 /* Return true if the Portable Executable behind ABFD uses the Cygwin dll
    (cygwin1.dll).  */