summaryrefslogtreecommitdiffstats
path: root/c/src/lib/librdbg/i386/excep_f.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/lib/librdbg/i386/excep_f.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/c/src/lib/librdbg/i386/excep_f.c b/c/src/lib/librdbg/i386/excep_f.c
new file mode 100644
index 0000000000..100b0d79d6
--- /dev/null
+++ b/c/src/lib/librdbg/i386/excep_f.c
@@ -0,0 +1,153 @@
+/*
+ **************************************************************************
+ *
+ * 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);
+ }
+}
+
+
+