| /* Support code for standard wait macros in gdb_wait.h. | 
 |  | 
 |    Copyright (C) 2019-2023 Free Software Foundation, Inc. | 
 |  | 
 |    This file is part of GDB. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #include "common-defs.h" | 
 |  | 
 | #include "gdb_wait.h" | 
 |  | 
 | #ifdef __MINGW32__ | 
 |  | 
 | /* The underlying idea is that when a Windows program is terminated by | 
 |    a fatal exception, its exit code is the value of that exception, as | 
 |    defined by the various EXCEPTION_* symbols in the Windows API | 
 |    headers.  We thus emulate WTERMSIG etc. by translating the fatal | 
 |    exception codes to more-or-less equivalent Posix signals. | 
 |  | 
 |    The translation below is not perfect, because a program could | 
 |    legitimately exit normally with a status whose value happens to | 
 |    have the high bits set, but that's extremely rare, to say the | 
 |    least, and it is deemed such a negligibly small probability of | 
 |    false positives is justified by the utility of reporting the | 
 |    terminating signal in the "normal" cases.  */ | 
 |  | 
 | # include <signal.h> | 
 |  | 
 | # define WIN32_LEAN_AND_MEAN | 
 | # include <windows.h>		/* for EXCEPTION_* constants */ | 
 |  | 
 | struct xlate_status | 
 | { | 
 |   /* The exit status (actually, fatal exception code).  */ | 
 |   DWORD status; | 
 |  | 
 |   /* The corresponding signal value.  */ | 
 |   int sig; | 
 | }; | 
 |  | 
 | int | 
 | windows_status_to_termsig (unsigned long status) | 
 | { | 
 |   static const xlate_status status_xlate_tbl[] = | 
 |     { | 
 |      {EXCEPTION_ACCESS_VIOLATION,	  SIGSEGV}, | 
 |      {EXCEPTION_IN_PAGE_ERROR,		  SIGSEGV}, | 
 |      {EXCEPTION_INVALID_HANDLE,		  SIGSEGV}, | 
 |      {EXCEPTION_ILLEGAL_INSTRUCTION,	  SIGILL}, | 
 |      {EXCEPTION_NONCONTINUABLE_EXCEPTION, SIGILL}, | 
 |      {EXCEPTION_ARRAY_BOUNDS_EXCEEDED,	  SIGSEGV}, | 
 |      {EXCEPTION_FLT_DENORMAL_OPERAND,	  SIGFPE}, | 
 |      {EXCEPTION_FLT_DIVIDE_BY_ZERO,	  SIGFPE}, | 
 |      {EXCEPTION_FLT_INEXACT_RESULT,	  SIGFPE}, | 
 |      {EXCEPTION_FLT_INVALID_OPERATION,	  SIGFPE}, | 
 |      {EXCEPTION_FLT_OVERFLOW,		  SIGFPE}, | 
 |      {EXCEPTION_FLT_STACK_CHECK,	  SIGFPE}, | 
 |      {EXCEPTION_FLT_UNDERFLOW,		  SIGFPE}, | 
 |      {EXCEPTION_INT_DIVIDE_BY_ZERO,	  SIGFPE}, | 
 |      {EXCEPTION_INT_OVERFLOW,		  SIGFPE}, | 
 |      {EXCEPTION_PRIV_INSTRUCTION,	  SIGILL}, | 
 |      {EXCEPTION_STACK_OVERFLOW,		  SIGSEGV}, | 
 |      {CONTROL_C_EXIT,			  SIGTERM} | 
 |     }; | 
 |  | 
 |   for (const xlate_status &x : status_xlate_tbl) | 
 |     if (x.status == status) | 
 |       return x.sig; | 
 |  | 
 |   return -1; | 
 | } | 
 |  | 
 | #endif	/* __MINGW32__ */ |