From 0f2265e2461babf685ff14f4ec9a9c60898453fe Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Wed, 8 Apr 2020 14:05:54 -0400 Subject: [PATCH] gdb: stop using host-dependent signal numbers in windows-tdep.c 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 | 24 +++++ gdb/amd64-windows-tdep.c | 10 +- gdb/i386-windows-tdep.c | 27 ++++- gdb/windows-tdep.c | 214 ++++++++++++++++++++++++++------------- gdb/windows-tdep.h | 9 ++ 5 files changed, 205 insertions(+), 79 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7ea85799211..6d958a2d9b8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2020-04-08 Simon Marchi + + * 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 * dwarf2/read.c (read_gdb_index_from_buffer): Remove objfile diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 6d5076d1c43..740152b7de8 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -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 diff --git a/gdb/i386-windows-tdep.c b/gdb/i386-windows-tdep.c index b26731c6bf2..3a07c862f23 100644 --- a/gdb/i386-windows-tdep.c +++ b/gdb/i386-windows-tdep.c @@ -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); } diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 662a46fe1d7..d1894ca0888 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -41,55 +41,69 @@ #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 = diff --git a/gdb/windows-tdep.h b/gdb/windows-tdep.h index f2dc4260469..cd7717bd917 100644 --- a/gdb/windows-tdep.h +++ b/gdb/windows-tdep.h @@ -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). */ -- 2.30.2