Back to index

glibc  2.9
exc2signal.c
Go to the documentation of this file.
00001 /* Translate Mach exception codes into signal numbers.  i386 version.
00002    Copyright (C) 1991,1992,1994,1996,1997,2001 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <hurd.h>
00021 #include <hurd/signal.h>
00022 #include <mach/exception.h>
00023 
00024 /* Translate the Mach exception codes, as received in an `exception_raise' RPC,
00025    into a signal number and signal subcode.  */
00026 
00027 void
00028 _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
00029 {
00030   detail->error = 0;
00031 
00032   switch (detail->exc)
00033     {
00034     default:
00035       *signo = SIGIOT;
00036       detail->code = detail->exc;
00037       break;
00038 
00039     case EXC_BAD_ACCESS:
00040       if (detail->exc_code == KERN_INVALID_ADDRESS
00041          || detail->exc_code == KERN_PROTECTION_FAILURE
00042          || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
00043        *signo = SIGSEGV;
00044       else
00045        *signo = SIGBUS;
00046       detail->code = detail->exc_subcode;
00047       detail->error = detail->exc_code;
00048       break;
00049 
00050     case EXC_BAD_INSTRUCTION:
00051       *signo = SIGILL;
00052       if (detail->exc_code == EXC_I386_INVOP)
00053        detail->code = ILL_INVOPR_FAULT;
00054       else if (detail->exc_code == EXC_I386_STKFLT)
00055        detail->code = ILL_STACK_FAULT;
00056       else
00057        detail->code = 0;
00058       break;
00059 
00060     case EXC_ARITHMETIC:
00061       switch (detail->exc_code)
00062        {
00063        case EXC_I386_DIV:   /* integer divide by zero */
00064          *signo = SIGFPE;
00065          detail->code = FPE_INTDIV_FAULT;
00066          break;
00067 
00068        case EXC_I386_INTO:  /* integer overflow */
00069          *signo = SIGFPE;
00070          detail->code = FPE_INTOVF_TRAP;
00071          break;
00072 
00073          /* These aren't anywhere documented or used in Mach 3.0.  */
00074        case EXC_I386_NOEXT:
00075        case EXC_I386_EXTOVR:
00076        default:
00077          *signo = SIGFPE;
00078          detail->code = 0;
00079          break;
00080 
00081        case EXC_I386_EXTERR:
00082          /* Subcode is the fp_status word saved by the hardware.
00083             Give an error code corresponding to the first bit set.  */
00084          if (detail->exc_subcode & FPS_IE)
00085            {
00086              *signo = SIGILL;
00087              detail->code = ILL_FPEOPR_FAULT;
00088            }
00089          else if (detail->exc_subcode & FPS_DE)
00090            {
00091              *signo = SIGFPE;
00092              detail->code = FPE_FLTDNR_FAULT;
00093            }
00094          else if (detail->exc_subcode & FPS_ZE)
00095            {
00096              *signo = SIGFPE;
00097              detail->code = FPE_FLTDIV_FAULT;
00098            }
00099          else if (detail->exc_subcode & FPS_OE)
00100            {
00101              *signo = SIGFPE;
00102              detail->code = FPE_FLTOVF_FAULT;
00103            }
00104          else if (detail->exc_subcode & FPS_UE)
00105            {
00106              *signo = SIGFPE;
00107              detail->code = FPE_FLTUND_FAULT;
00108            }
00109          else if (detail->exc_subcode & FPS_PE)
00110            {
00111              *signo = SIGFPE;
00112              detail->code = FPE_FLTINX_FAULT;
00113            }
00114          else
00115            {
00116              *signo = SIGFPE;
00117              detail->code = 0;
00118            }
00119          break;
00120 
00121          /* These two can only be arithmetic exceptions if we
00122             are in V86 mode, which sounds like emulation to me.
00123             (See Mach 3.0 i386/trap.c.)  */
00124        case EXC_I386_EMERR:
00125          *signo = SIGFPE;
00126          detail->code = FPE_EMERR_FAULT;
00127          break;
00128        case EXC_I386_BOUND:
00129          *signo = SIGFPE;
00130          detail->code = FPE_EMBND_FAULT;
00131          break;
00132        }
00133       break;
00134 
00135     case EXC_EMULATION:
00136       /* 3.0 doesn't give this one, why, I don't know.  */
00137       *signo = SIGEMT;
00138       detail->code = 0;
00139       break;
00140 
00141     case EXC_SOFTWARE:
00142       /* The only time we get this in Mach 3.0
00143         is for an out of bounds trap.  */
00144       if (detail->exc_code == EXC_I386_BOUND)
00145        {
00146          *signo = SIGFPE;
00147          detail->code = FPE_SUBRNG_FAULT;
00148        }
00149       else
00150        {
00151          *signo = SIGEMT;
00152          detail->code = 0;
00153        }
00154       break;
00155 
00156     case EXC_BREAKPOINT:
00157       *signo = SIGTRAP;
00158       if (detail->exc_code == EXC_I386_SGL)
00159        detail->code = DBG_SINGLE_TRAP;
00160       else if (detail->exc_code == EXC_I386_BPT)
00161        detail->code = DBG_BRKPNT_FAULT;
00162       else
00163        detail->code = 0;
00164       break;
00165     }
00166 }