summaryrefslogblamecommitdiffstats
path: root/c/src/librdbg/src/i386/excep_f.c
blob: d994e4f7e5412b06cfee33917bbfe9e2b44ede05 (plain) (tree)























                                                                           

                                    
 
                              
 



























                                          

 






                                               

                                            



                           
                                                                          

                                                           

                                                
                        
                                                                            

                        
 


                                                       













                                                                              

      






                                                                           
                                   

                                                             

                                                                     

                            
                              
                                           
                                


                                                 

                                   


                                                 

                                   

                                                 


            

                                                 


            

                                                                         
                                                
                                           

   
/*
 **************************************************************************
 *
 * Component =   
 * 
 * Synopsis  =   rdbg/i386/excep.c
 *
 * $Id$
 *
 **************************************************************************
 */

#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>

/* -----------------------------------------------------------------
   Maping of hardware exceptions into Unix-like signal numbers.
   It is identical to the one used by the PM and the AM.
   ----------------------------------------------------------------- */

  int
ExcepToSig (Exception_context * ctx)
{
  int excep = getExcNum (ctx);

  switch (excep) {

  case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
  case I386_EXCEPTION_I386_COPROC_SEG_ERR:
  case I386_EXCEPTION_FLOAT_ERROR:
  case I386_EXCEPTION_BOUND:
    return SIGFPE;

  case I386_EXCEPTION_DEBUG:
  case I386_EXCEPTION_BREAKPOINT:
  case I386_EXCEPTION_ENTER_RDBG:
    return SIGTRAP;

  case I386_EXCEPTION_OVERFLOW:
  case I386_EXCEPTION_DIVIDE_BY_ZERO:
  case I386_EXCEPTION_ILLEGAL_INSTR:
    return SIGILL;

  case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
  case I386_EXCEPTION_STACK_SEGMENT_FAULT:
  case I386_EXCEPTION_GENERAL_PROT_ERR:
  case I386_EXCEPTION_PAGE_FAULT:
    return SIGSEGV;

  default:
    break;
  }
  return SIGKILL;
}

/*----- Breakpoint Exception management -----*/

    /*
     *  Handler for Breakpoint Exceptions :
     *  software breakpoints.
     */

  void
BreakPointExcHdl (CPU_Exception_frame * ctx)
{
  rtems_status_code status;
  rtems_id continueSemId;

  if ((justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG)) {
    PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
    justSaveContext = 0;
  } else {
    if (ctx->idtIndex != I386_EXCEPTION_DEBUG) {
      NbSerializedCtx++;
      rtems_semaphore_obtain (serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
      NbSerializedCtx--;
    }

    currentTargetThread = _Thread_Executing->Object.id;

#ifdef DDEBUG
    printk ("----------------------------------------------------------\n");
    printk ("Exception %d caught at PC %x by thread %d\n",
            ctx->idtIndex, ctx->eip, _Thread_Executing->Object.id);
    printk ("----------------------------------------------------------\n");
    printk ("Processor execution context at time of the fault was  :\n");
    printk ("----------------------------------------------------------\n");
    printk (" EAX = %x	EBX = %x	ECX = %x	EDX = %x\n",
            ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
    printk (" ESI = %x	EDI = %x	EBP = %x	ESP = %x\n",
            ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
    printk ("----------------------------------------------------------\n");
    printk ("Error code pushed by processor itself (if not 0) = %x\n",
            ctx->faultCode);
    printk ("----------------------------------------------------------\n\n");
#endif

    status = rtems_semaphore_create (rtems_build_name ('D', 'B', 'G', 'c'),
                                     0,
                                     RTEMS_FIFO |
                                     RTEMS_COUNTING_SEMAPHORE |
                                     RTEMS_NO_INHERIT_PRIORITY |
                                     RTEMS_NO_PRIORITY_CEILING |
                                     RTEMS_LOCAL, 0, &continueSemId);
    if (status != RTEMS_SUCCESSFUL)
      rtems_panic ("Can't create continue semaphore: `%s'\n",
                   rtems_status_text (status));

    PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);

    switch (ctx->idtIndex) {
    case I386_EXCEPTION_DEBUG:
      DPRINTF ((" DEBUG EXCEPTION !!!\n"));
      ctx->eflags &= ~EFLAGS_TF;
      ExitForSingleStep--;
      rtems_semaphore_release (wakeupEventSemId);
      break;

    case I386_EXCEPTION_BREAKPOINT:
      DPRINTF ((" BREAKPOINT EXCEPTION !!!\n"));
      rtems_semaphore_release (wakeupEventSemId);
      break;

    case I386_EXCEPTION_ENTER_RDBG:
      DPRINTF ((" ENTER RDBG !!!\n"));
      rtems_semaphore_release (wakeupEventSemId);
      break;

    default:
      DPRINTF ((" OTHER EXCEPTION !!!\n"));
      rtems_semaphore_release (wakeupEventSemId);
      break;
    }

    rtems_semaphore_obtain (continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);

    PopExceptCtx (_Thread_Executing->Object.id);
    rtems_semaphore_delete (continueSemId);
  }
}