[PATCH] libdebugger: Use an offset table to format GDB `g` packets.

chrisj at rtems.org chrisj at rtems.org
Mon Apr 8 03:33:13 UTC 2019


From: Chris Johns <chrisj at rtems.org>

Adding support for a register offset table lets FPU registers
be supported if added to the backend.

Closes #3733.
---
 .../rtems/debugger/rtems-debugger-server.h    |   7 +-
 cpukit/libdebugger/rtems-debugger-arm.c       | 281 ++++++++++++------
 cpukit/libdebugger/rtems-debugger-i386.c      | 209 +++++++++----
 cpukit/libdebugger/rtems-debugger-server.c    |  40 ++-
 cpukit/libdebugger/rtems-debugger-target.c    |  68 +++--
 cpukit/libdebugger/rtems-debugger-target.h    |  30 +-
 cpukit/libdebugger/rtems-debugger-threads.c   |  13 +-
 cpukit/libdebugger/rtems-debugger-threads.h   |   4 +-
 8 files changed, 463 insertions(+), 189 deletions(-)

diff --git a/cpukit/include/rtems/debugger/rtems-debugger-server.h b/cpukit/include/rtems/debugger/rtems-debugger-server.h
index a345d7649e..2189aac873 100644
--- a/cpukit/include/rtems/debugger/rtems-debugger-server.h
+++ b/cpukit/include/rtems/debugger/rtems-debugger-server.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Chris Johns <chrisj at rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj at rtems.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -176,6 +176,11 @@ extern void rtems_debugger_unlock(void);
  */
 extern bool rtems_debugger_server_running(void);
 
+/**
+ * Signel a server crash.
+ */
+extern void rtems_debugger_server_crash(void);
+
 /**
  * Get the remote handle from the debugger.
  */
diff --git a/cpukit/libdebugger/rtems-debugger-arm.c b/cpukit/libdebugger/rtems-debugger-arm.c
index 722dd54924..c71af42a02 100644
--- a/cpukit/libdebugger/rtems-debugger-arm.c
+++ b/cpukit/libdebugger/rtems-debugger-arm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Chris Johns <chrisj at rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj at rtems.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -116,18 +116,13 @@
 #define RTEMS_DEBUGGER_NUMREGS 26
 
 /*
- * Number of bytes per register.
+ * Number of bytes per type of register.
  */
-#define RTEMS_DEBUGGER_REGBYTES 4
+#define RTEMS_DEBUGGER_REG_BYTES    4
+#define RTEMS_DEBUGGER_FP_REG_BYTES 12
 
 /*
- * Number of bytes of registers.
- */
-#define RTEMS_DEBUGGER_NUMREGBYTES \
-  (RTEMS_DEBUGGER_NUMREGS * RTEMS_DEBUGGER_REGBYTES)
-
-/*
- * Debugger registers layout.
+ * Debugger registers layout. See arm-core.xml in GDB source.
  */
 #define REG_R0    0
 #define REG_R1    1
@@ -145,8 +140,60 @@
 #define REG_SP    13
 #define REG_LR    14
 #define REG_PC    15
+#define REG_F0    16
+#define REG_F1    17
+#define REG_F2    18
+#define REG_F3    19
+#define REG_F4    20
+#define REG_F5    21
+#define REG_F6    22
+#define REG_F7    23
+#define REG_FPS   24
 #define REG_CPSR  25
 
+/**
+ * Register offset table with the total as the last entry.
+ *
+ * Check this table in gdb with the command:
+ *
+ *   maint print registers
+ */
+static const size_t arm_reg_offsets[RTEMS_DEBUGGER_NUMREGS + 1] =
+{
+  0,   /* REG_R0    4 uint32_t */
+  4,   /* REG_R1    4 uint32_t */
+  8,   /* REG_R2    4 uint32_t */
+  12,  /* REG_R3    4 uint32_t */
+  16,  /* REG_R4    4 uint32_t */
+  20,  /* REG_R5    4 uint32_t */
+  24,  /* REG_R6    4 uint32_t */
+  28,  /* REG_R7    4 uint32_t */
+  32,  /* REG_R8    4 uint32_t */
+  36,  /* REG_R9    4 uint32_t */
+  40,  /* REG_R10   4 uint32_t */
+  44,  /* REG_R11   4 uint32_t */
+  48,  /* REG_R12   4 uint32_t */
+  52,  /* REG_SP    4 *1 */
+  56,  /* REG_LR    4 uint32_t */
+  60,  /* REG_PC    4 *1 */
+  64,  /* REG_F0   12 _arm_ext */
+  76,  /* REG_F1   12 _arm_ext */
+  88,  /* REG_F2   12 _arm_ext */
+  100, /* REG_F3   12 _arm_ext */
+  112, /* REG_F4   12 _arm_ext */
+  124, /* REG_F5   12 _arm_ext */
+  136, /* REG_F6   12 _arm_ext */
+  148, /* REG_F7   12 _arm_ext */
+  160, /* REG_FPS   4 uint32_t */
+  164, /* REG_CPSR  4 uint32_t */
+  168  /* total size */
+};
+
+/*
+ * Number of bytes of registers.
+ */
+#define RTEMS_DEBUGGER_NUMREGBYTES arm_reg_offsets[RTEMS_DEBUGGER_NUMREGS]
+
 /**
  * The various status registers.
  */
@@ -235,8 +282,13 @@ target_printk(const char* format, ...)
   rtems_debugger_printk_unlock(&lock_context);
   va_end(ap);
 }
+#else
+#define target_printk(_fmt, ...)
+#define mode_labels(_m) NULL
+#endif
+
 static const char*
-mode_label(int mode)
+arm_mode_label(int mode)
 {
   switch (mode) {
   case 0x10:
@@ -260,10 +312,6 @@ mode_label(int mode)
   }
   return "---";
 }
-#else
-#define target_printk(_fmt, ...)
-#define mode_labels(_m) NULL
-#endif
 
 /*
  * CP register access.
@@ -577,7 +625,7 @@ rtems_debugger_target_configure(rtems_debugger_target* target)
 {
   target->capabilities = (RTEMS_DEBUGGER_TARGET_CAP_SWBREAK);
   target->reg_num = RTEMS_DEBUGGER_NUMREGS;
-  target->reg_size = sizeof(uint32_t);
+  target->reg_offset = arm_reg_offsets;
   target->breakpoint = &breakpoint[0];
   target->breakpoint_size = sizeof(breakpoint);
   return arm_debug_probe(target);
@@ -590,7 +638,7 @@ target_exception(CPU_Exception_frame* frame)
   uint32_t ifsr = arm_cp15_get_instruction_fault_status();
 #endif
 
-  target_printk("[} frame = %08lx sig=%d vector=%x ifsr=%08lx pra=%08x\n",
+  target_printk("[} frame = %08" PRIx32 " sig=%d vector=%x ifsr=%08" PRIx32 " pra=%08x\n",
                 (uint32_t) frame,
                 rtems_debugger_target_exception_to_signal(frame),
                 frame->vector, ifsr, (intptr_t) frame->register_pc);
@@ -632,7 +680,7 @@ target_exception(CPU_Exception_frame* frame)
                 (FRAME_SR & (1 <<  5)) != 0 ? 'T' : '-',
                 ((FRAME_SR >> (25 - 5)) & (0x3 << 5)) | ((FRAME_SR >> 10) & 0x1f),
                 (FRAME_SR >> 16) & 0xf,
-                FRAME_SR & 0x1f, mode_label(FRAME_SR & 0x1f));
+                FRAME_SR & 0x1f, arm_mode_label(FRAME_SR & 0x1f));
 
   arm_debug_break_clear();
 
@@ -652,7 +700,7 @@ target_exception(CPU_Exception_frame* frame)
     break;
   }
 
-  target_printk("[} resuming frame = %08lx PC = %08" PRIxPTR " CPSR = %08" PRIx32 "\n",
+  target_printk("[} resuming frame = %08" PRIx32 " PC = %08" PRIxPTR " CPSR = %08" PRIx32 "\n",
                 (uint32_t) frame, (intptr_t) frame->register_pc, FRAME_SR);
 }
 
@@ -986,6 +1034,34 @@ rtems_debugger_target_set_vectors(void)
 }
 #endif
 
+static bool
+rtems_debugger_is_int_reg(size_t reg)
+{
+  const size_t size = arm_reg_offsets[reg + 1] - arm_reg_offsets[reg];
+  return size == RTEMS_DEBUGGER_REG_BYTES;
+}
+
+static void
+rtems_debugger_set_int_reg(rtems_debugger_thread* thread,
+                           size_t                 reg,
+                           const uint32_t         value)
+{
+  const size_t offset = arm_reg_offsets[reg];
+  /*
+   * Use memcpy to avoid alignment issues.
+   */
+  memcpy(&thread->registers[offset], &value, sizeof(uint32_t));
+}
+
+static const uint32_t
+rtems_debugger_get_int_reg(rtems_debugger_thread* thread, size_t reg)
+{
+  const size_t offset = arm_reg_offsets[reg];
+  uint32_t     value;
+  memcpy(&value, &thread->registers[offset], sizeof(uint32_t));
+  return value;
+}
+
 int
 rtems_debugger_target_enable(void)
 {
@@ -1028,11 +1104,14 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
   if (!rtems_debugger_thread_flag(thread,
                                   RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID)) {
     static const uint32_t good_address = (uint32_t) &good_address;
-    uint32_t*             regs = &thread->registers[0];
     int                   i;
 
-    for (i = 0; i < RTEMS_DEBUGGER_NUMREGS; ++i)
-      regs[i] = (uint32_t) &good_address;
+    memset(&thread->registers[0], 0, RTEMS_DEBUGGER_NUMREGBYTES);
+
+    for (i = 0; i < RTEMS_DEBUGGER_NUMREGS; ++i) {
+      if (rtems_debugger_is_int_reg(i))
+        rtems_debugger_set_int_reg(thread, i, (uint32_t) &good_address);
+    }
 
     if (thread->frame) {
       CPU_Exception_frame* frame = thread->frame;
@@ -1050,23 +1129,23 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
         thread->flags = ~RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED;
       }
 
-      regs[REG_R0]   = frame->register_r0;
-      regs[REG_R1]   = frame->register_r1;
-      regs[REG_R2]   = frame->register_r2;
-      regs[REG_R3]   = frame->register_r3;
-      regs[REG_R4]   = frame->register_r4;
-      regs[REG_R5]   = frame->register_r5;
-      regs[REG_R6]   = frame->register_r6;
-      regs[REG_R7]   = frame->register_r7;
-      regs[REG_R8]   = frame->register_r8;
-      regs[REG_R9]   = frame->register_r9;
-      regs[REG_R10]  = frame->register_r10;
-      regs[REG_R11]  = frame->register_r11;
-      regs[REG_R12]  = frame->register_r12;
-      regs[REG_SP]   = frame->register_sp;
-      regs[REG_LR]   = (uint32_t) frame->register_lr;
-      regs[REG_PC]   = (uint32_t) frame->register_pc;
-      regs[REG_CPSR] = FRAME_SR;
+      rtems_debugger_set_int_reg(thread, REG_R0,   frame->register_r0);
+      rtems_debugger_set_int_reg(thread, REG_R1,   frame->register_r1);
+      rtems_debugger_set_int_reg(thread, REG_R2,   frame->register_r2);
+      rtems_debugger_set_int_reg(thread, REG_R3,   frame->register_r3);
+      rtems_debugger_set_int_reg(thread, REG_R4,   frame->register_r4);
+      rtems_debugger_set_int_reg(thread, REG_R5,   frame->register_r5);
+      rtems_debugger_set_int_reg(thread, REG_R6,   frame->register_r6);
+      rtems_debugger_set_int_reg(thread, REG_R7,   frame->register_r7);
+      rtems_debugger_set_int_reg(thread, REG_R8,   frame->register_r8);
+      rtems_debugger_set_int_reg(thread, REG_R9,   frame->register_r9);
+      rtems_debugger_set_int_reg(thread, REG_R10,  frame->register_r10);
+      rtems_debugger_set_int_reg(thread, REG_R11,  frame->register_r11);
+      rtems_debugger_set_int_reg(thread, REG_R12,  frame->register_r12);
+      rtems_debugger_set_int_reg(thread, REG_SP,   frame->register_sp);
+      rtems_debugger_set_int_reg(thread, REG_LR,   (uint32_t) frame->register_lr);
+      rtems_debugger_set_int_reg(thread, REG_PC,   (uint32_t) frame->register_pc);
+      rtems_debugger_set_int_reg(thread, REG_CPSR, FRAME_SR);
       /*
        * Get the signal from the frame.
        */
@@ -1074,29 +1153,29 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
     }
     else {
 #if defined(ARM_MULTILIB_ARCH_V4)
-      regs[REG_R4]  = thread->tcb->Registers.register_r4;
-      regs[REG_R5]  = thread->tcb->Registers.register_r5;
-      regs[REG_R6]  = thread->tcb->Registers.register_r6;
-      regs[REG_R7]  = thread->tcb->Registers.register_r7;
-      regs[REG_R8]  = thread->tcb->Registers.register_r8;
-      regs[REG_R9]  = thread->tcb->Registers.register_r9;
-      regs[REG_R10] = thread->tcb->Registers.register_r10;
-      regs[REG_R11] = thread->tcb->Registers.register_fp;
-      regs[REG_LR]  = (intptr_t) thread->tcb->Registers.register_lr;
-      regs[REG_PC]  = (intptr_t) thread->tcb->Registers.register_lr;
-      regs[REG_SP]  = (intptr_t) thread->tcb->Registers.register_sp;
+      rtems_debugger_set_int_reg(thread, REG_R4,  thread->tcb->Registers.register_r4);
+      rtems_debugger_set_int_reg(thread, REG_R5,  thread->tcb->Registers.register_r5);
+      rtems_debugger_set_int_reg(thread, REG_R6,  thread->tcb->Registers.register_r6);
+      rtems_debugger_set_int_reg(thread, REG_R7,  thread->tcb->Registers.register_r7);
+      rtems_debugger_set_int_reg(thread, REG_R8,  thread->tcb->Registers.register_r8);
+      rtems_debugger_set_int_reg(thread, REG_R9,  thread->tcb->Registers.register_r9);
+      rtems_debugger_set_int_reg(thread, REG_R10, thread->tcb->Registers.register_r10);
+      rtems_debugger_set_int_reg(thread, REG_R11, thread->tcb->Registers.register_fp);
+      rtems_debugger_set_int_reg(thread, REG_LR,  (intptr_t) thread->tcb->Registers.register_lr);
+      rtems_debugger_set_int_reg(thread, REG_PC,  (intptr_t) thread->tcb->Registers.register_lr);
+      rtems_debugger_set_int_reg(thread, REG_SP,  (intptr_t) thread->tcb->Registers.register_sp);
 #elif defined(ARM_MULTILIB_ARCH_V7M)
-      regs[REG_R4]  = thread->tcb->Registers.register_r4;
-      regs[REG_R5]  = thread->tcb->Registers.register_r5;
-      regs[REG_R6]  = thread->tcb->Registers.register_r6;
-      regs[REG_R7]  = thread->tcb->Registers.register_r7;
-      regs[REG_R8]  = thread->tcb->Registers.register_r8;
-      regs[REG_R9]  = thread->tcb->Registers.register_r9;
-      regs[REG_R10] = thread->tcb->Registers.register_r10;
-      regs[REG_R11] = thread->tcb->Registers.register_r11;
-      regs[REG_LR]  = (intptr_t) thread->tcb->Registers.register_lr;
-      regs[REG_PC]  = (intptr_t) thread->tcb->Registers.register_lr;
-      regs[REG_SP]  = (intptr_t) thread->tcb->Registers.register_sp;
+      rtems_debugger_set_int_reg(thread, REG_R4,  thread->tcb->Registers.register_r4);
+      rtems_debugger_set_int_reg(thread, REG_R5,  thread->tcb->Registers.register_r5);
+      rtems_debugger_set_int_reg(thread, REG_R6,  thread->tcb->Registers.register_r6);
+      rtems_debugger_set_int_reg(thread, REG_R7,  thread->tcb->Registers.register_r7);
+      rtems_debugger_set_int_reg(thread, REG_R8,  thread->tcb->Registers.register_r8);
+      rtems_debugger_set_int_reg(thread, REG_R9,  thread->tcb->Registers.register_r9);
+      rtems_debugger_set_int_reg(thread, REG_R10, thread->tcb->Registers.register_r10);
+      rtems_debugger_set_int_reg(thread, REG_R11, thread->tcb->Registers.register_r11);
+      rtems_debugger_set_int_reg(thread, REG_LR,  (intptr_t) thread->tcb->Registers.register_lr);
+      rtems_debugger_set_int_reg(thread, REG_PC,  (intptr_t) thread->tcb->Registers.register_lr);
+      rtems_debugger_set_int_reg(thread, REG_SP,  (intptr_t) thread->tcb->Registers.register_sp);
 #endif
       /*
        * Blocked threads have no signal.
@@ -1116,8 +1195,6 @@ rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
 {
   if (rtems_debugger_thread_flag(thread,
                                  RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY)) {
-    uint32_t* regs = &thread->registers[0];
-
     /*
      * Only write to debugger controlled exception threads. Do not touch the
      * registers for threads blocked in the context switcher.
@@ -1125,23 +1202,23 @@ rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
     if (rtems_debugger_thread_flag(thread,
                                    RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
       CPU_Exception_frame* frame = thread->frame;
-      frame->register_r0  = regs[REG_R0];
-      frame->register_r1  = regs[REG_R1];
-      frame->register_r2  = regs[REG_R2];
-      frame->register_r3  = regs[REG_R3];
-      frame->register_r4  = regs[REG_R4];
-      frame->register_r5  = regs[REG_R5];
-      frame->register_r6  = regs[REG_R6];
-      frame->register_r7  = regs[REG_R7];
-      frame->register_r8  = regs[REG_R8];
-      frame->register_r9  = regs[REG_R9];
-      frame->register_r10 = regs[REG_R10];
-      frame->register_r11 = regs[REG_R11];
-      frame->register_r12 = regs[REG_R12];
-      frame->register_sp  = regs[REG_SP];
-      frame->register_lr  = (void*) regs[REG_LR];
-      frame->register_pc  = (void*) regs[REG_PC];
-      FRAME_SR            = regs[REG_CPSR];
+      frame->register_r0  = rtems_debugger_get_int_reg(thread, REG_R0);
+      frame->register_r1  = rtems_debugger_get_int_reg(thread, REG_R1);
+      frame->register_r2  = rtems_debugger_get_int_reg(thread, REG_R2);
+      frame->register_r3  = rtems_debugger_get_int_reg(thread, REG_R3);
+      frame->register_r4  = rtems_debugger_get_int_reg(thread, REG_R4);
+      frame->register_r5  = rtems_debugger_get_int_reg(thread, REG_R5);
+      frame->register_r6  = rtems_debugger_get_int_reg(thread, REG_R6);
+      frame->register_r7  = rtems_debugger_get_int_reg(thread, REG_R7);
+      frame->register_r8  = rtems_debugger_get_int_reg(thread, REG_R8);
+      frame->register_r9  = rtems_debugger_get_int_reg(thread, REG_R9);
+      frame->register_r10 = rtems_debugger_get_int_reg(thread, REG_R10);
+      frame->register_r11 = rtems_debugger_get_int_reg(thread, REG_R11);
+      frame->register_r12 = rtems_debugger_get_int_reg(thread, REG_R12);
+      frame->register_sp  = rtems_debugger_get_int_reg(thread, REG_SP);
+      frame->register_lr  = (void*) rtems_debugger_get_int_reg(thread, REG_LR);
+      frame->register_pc  = (void*) rtems_debugger_get_int_reg(thread, REG_PC);
+      FRAME_SR            = rtems_debugger_get_int_reg(thread, REG_CPSR);
     }
     thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
   }
@@ -1154,8 +1231,7 @@ rtems_debugger_target_reg_pc(rtems_debugger_thread* thread)
   int r;
   r = rtems_debugger_target_read_regs(thread);
   if (r >= 0) {
-    uint32_t* regs = &thread->registers[0];
-    return regs[REG_PC];
+    return rtems_debugger_get_int_reg(thread, REG_PC);
   }
   return 0;
 }
@@ -1172,8 +1248,7 @@ rtems_debugger_target_reg_sp(rtems_debugger_thread* thread)
   int r;
   r = rtems_debugger_target_read_regs(thread);
   if (r >= 0) {
-    uint32_t* regs = &thread->registers[0];
-    return regs[REG_SP];
+    return rtems_debugger_get_int_reg(thread, REG_SP);
   }
   return 0;
 }
@@ -1293,6 +1368,44 @@ rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame)
   return sig;
 }
 
+void
+rtems_debugger_target_exception_print(CPU_Exception_frame* frame)
+{
+  rtems_debugger_printf("  R0 = %08" PRIx32 "  R1 = %08" PRIx32       \
+                        "  R2 = %08" PRIx32 "  R3 = %08" PRIx32 "\n",
+                        frame->register_r0, frame->register_r1,
+                        frame->register_r2, frame->register_r3);
+  rtems_debugger_printf("  R4 = %08" PRIx32 "  R5 = %08" PRIx32       \
+                        "  R6 = %08" PRIx32 "  R7 = %08" PRIx32 "\n",
+                        frame->register_r4, frame->register_r5,
+                        frame->register_r6, frame->register_r7);
+  rtems_debugger_printf("  R8 = %08" PRIx32 "  R9 = %08" PRIx32       \
+                        " R10 = %08" PRIx32 " R11 = %08" PRIx32 "\n",
+                        frame->register_r8, frame->register_r9,
+                        frame->register_r10, frame->register_r11);
+  rtems_debugger_printf(" R12 = %08" PRIx32 "  SP = %08" PRIx32       \
+                        "  LR = %08" PRIxPTR "  PC = %08" PRIxPTR "\n", \
+                        frame->register_r12, frame->register_sp,
+                        (intptr_t) frame->register_lr, (intptr_t) frame->register_pc);
+  rtems_debugger_printf(" CPSR = %08" PRIx32 " %c%c%c%c%c%c%c%c%c%c%c"       \
+                        " GE:%" PRIx32 " IT:%02" PRIx32 " M:%" PRIx32 " %s\n",
+                        FRAME_SR,
+                        (FRAME_SR & (1 << 31)) != 0 ? 'N' : '-',
+                        (FRAME_SR & (1 << 30)) != 0 ? 'Z' : '-',
+                        (FRAME_SR & (1 << 29)) != 0 ? 'C' : '-',
+                        (FRAME_SR & (1 << 28)) != 0 ? 'V' : '-',
+                        (FRAME_SR & (1 << 27)) != 0 ? 'Q' : '-',
+                        (FRAME_SR & (1 << 24)) != 0 ? 'J' : '-',
+                        (FRAME_SR & (1 <<  9)) != 0 ? 'E' : '-',
+                        (FRAME_SR & (1 <<  8)) != 0 ? 'A' : '-',
+                        (FRAME_SR & (1 <<  7)) != 0 ? 'I' : '-',
+                        (FRAME_SR & (1 <<  6)) != 0 ? 'F' : '-',
+                        (FRAME_SR & (1 <<  5)) != 0 ? 'T' : '-',
+                        ((FRAME_SR >> (25 - 5)) & (0x3 << 5)) | ((FRAME_SR >> 10) & 0x1f),
+                        (FRAME_SR >> 16) & 0xf,
+                        FRAME_SR & 0x1f, arm_mode_label(FRAME_SR & 0x1f));
+}
+
 int
 rtems_debugger_target_hwbreak_insert(void)
 {
diff --git a/cpukit/libdebugger/rtems-debugger-i386.c b/cpukit/libdebugger/rtems-debugger-i386.c
index 9da6031574..a2396e5f30 100644
--- a/cpukit/libdebugger/rtems-debugger-i386.c
+++ b/cpukit/libdebugger/rtems-debugger-i386.c
@@ -53,13 +53,7 @@
 /*
  * Number of bytes per register.
  */
-#define RTEMS_DEBUGGER_REGBYTES 4
-
-/*
- * Number of bytes of registers.
- */
-#define RTEMS_DEBUGGER_NUMREGBYTES \
-  (RTEMS_DEBUGGER_NUMREGS * RTEMS_DEBUGGER_REGBYTES)
+#define RTEMS_DEBUGGER_REG_BYTES 4
 
 /*
  * Debugger registers layout.
@@ -83,6 +77,39 @@
 #define REG_FS     14
 #define REG_GS     15
 
+/**
+ * Register offset table with the total as the last entry.
+ *
+ * Check this table in gdb with the command:
+ *
+ *   maint print registers
+ */
+static const size_t i386_reg_offsets[RTEMS_DEBUGGER_NUMREGS + 1] =
+{
+  0,   /* REG_EAX    4 uint32_t */
+  4,   /* REG_ECX    4 uint32_t */
+  8,   /* REG_EDX    4 uint32_t */
+  12,  /* REG_EBX    4 uint32_t */
+  16,  /* REG_ESP    4 uint32_t */
+  20,  /* REG_EBP    4 uint32_t */
+  24,  /* REG_ESI    4 uint32_t */
+  28,  /* REG_EDI    4 uint32_t */
+  32,  /* REG_EIP    4 *1 */
+  36,  /* REG_EFLAGS 4 uint32_t */
+  40,  /* REG_CS     4 uint32_t */
+  44,  /* REG_SS     4 uint32_t */
+  48,  /* REG_DS     4 uint32_t */
+  52,  /* REG_ES     4 uint32_t */
+  56,  /* REG_FS     4 uint32_t */
+  60,  /* REG_GS     4 uint32_t */
+  64   /* total size */
+};
+
+/*
+ * Number of bytes of registers.
+ */
+#define RTEMS_DEBUGGER_NUMREGBYTES i386_reg_offsets[RTEMS_DEBUGGER_NUMREGS]
+
 /**
  * The int 3 opcode.
  */
@@ -96,14 +123,34 @@ static const uint8_t breakpoint[1] = { TARGET_BKPT };
 #define GET_REG(_r, _v) asm volatile("pushl %%" #_r "; popl %0" : "=rm" (_v))
 
 /*
- * Get a copy of a segment register.
+ * A function to get a segment register.
  */
-#define GET_SEG_REG(_r, _v) \
-  do {                      \
-    int _i;                 \
-    GET_REG(_r, _i);        \
-    _v = _i & 0xffff;       \
-  } while (0)
+static inline uint32_t
+get_seg_reg(size_t reg)
+{
+  int v = 0;
+  switch (reg) {
+    case REG_CS:
+      GET_REG(CS, v);
+      break;
+    case REG_SS:
+      GET_REG(SS, v);
+      break;
+    case REG_DS:
+      GET_REG(DS, v);
+      break;
+    case REG_ES:
+      GET_REG(ES, v);
+      break;
+    case REG_FS:
+      GET_REG(FS, v);
+      break;
+    case REG_GS:
+      GET_REG(GS, v);
+      break;
+  }
+  return v & 0xffff;
+}
 
 /**
  * Target lock.
@@ -149,7 +196,7 @@ rtems_debugger_target_configure(rtems_debugger_target* target)
 {
   target->capabilities = (RTEMS_DEBUGGER_TARGET_CAP_SWBREAK);
   target->reg_num = RTEMS_DEBUGGER_NUMREGS;
-  target->reg_size = sizeof(uint32_t);
+  target->reg_offset = i386_reg_offsets;
   target->breakpoint = &breakpoint[0];
   target->breakpoint_size = sizeof(breakpoint);
   return 0;
@@ -158,7 +205,7 @@ rtems_debugger_target_configure(rtems_debugger_target* target)
 static void
 target_exception(CPU_Exception_frame* frame)
 {
-  target_printk("[} frame = %08lx sig=%d (%lx)\n",
+  target_printk("[} frame = %08" PRIx32 " sig=%d (%" PRIx32 ")\n",
                 (uint32_t) frame,
                 rtems_debugger_target_exception_to_signal(frame),
                 frame->idtIndex);
@@ -185,6 +232,34 @@ target_exception(CPU_Exception_frame* frame)
   }
 }
 
+static bool
+rtems_debugger_is_int_reg(size_t reg)
+{
+  const size_t size = i386_reg_offsets[reg + 1] - i386_reg_offsets[reg];
+  return size == RTEMS_DEBUGGER_REG_BYTES;
+}
+
+static void
+rtems_debugger_set_int_reg(rtems_debugger_thread* thread,
+                           size_t                 reg,
+                           const uint32_t         value)
+{
+  const size_t offset = i386_reg_offsets[reg];
+  /*
+   * Use memcpy to avoid alignment issues.
+   */
+  memcpy(&thread->registers[offset], &value, sizeof(uint32_t));
+}
+
+static const uint32_t
+rtems_debugger_get_int_reg(rtems_debugger_thread* thread, size_t reg)
+{
+  const size_t offset = i386_reg_offsets[reg];
+  uint32_t     value;
+  memcpy(&value, &thread->registers[offset], sizeof(uint32_t));
+  return value;
+}
+
 int
 rtems_debugger_target_enable(void)
 {
@@ -214,25 +289,27 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
 {
   if (!rtems_debugger_thread_flag(thread,
                                   RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID)) {
-    uint32_t* regs = &thread->registers[0];
-    size_t    i;
+    size_t i;
 
-    for (i = 0; i < rtems_debugger_target_reg_num(); ++i)
-      regs[i] = 0xdeaddead;
+    for (i = 0; i < rtems_debugger_target_reg_num(); ++i) {
+      if (rtems_debugger_is_int_reg(i))
+        rtems_debugger_set_int_reg(thread, i, 0xdeaddead);
+    }
 
     if (thread->frame) {
       CPU_Exception_frame* frame = thread->frame;
-      regs[REG_EAX]    = frame->eax;
-      regs[REG_ECX]    = frame->ecx;
-      regs[REG_EDX]    = frame->edx;
-      regs[REG_EBX]    = frame->ebx;
-      regs[REG_ESP]    = frame->esp0;
-      regs[REG_EBP]    = frame->ebp;
-      regs[REG_ESI]    = frame->esi;
-      regs[REG_EDI]    = frame->edi;
-      regs[REG_EIP]    = frame->eip;
-      regs[REG_EFLAGS] = frame->eflags;
-      regs[REG_CS]     = frame->cs;
+
+      rtems_debugger_set_int_reg(thread, REG_EAX,    frame->eax);
+      rtems_debugger_set_int_reg(thread, REG_ECX,    frame->ecx);
+      rtems_debugger_set_int_reg(thread, REG_EDX,    frame->edx);
+      rtems_debugger_set_int_reg(thread, REG_EBX,    frame->ebx);
+      rtems_debugger_set_int_reg(thread, REG_ESP,    frame->esp0);
+      rtems_debugger_set_int_reg(thread, REG_EBP,    frame->ebp);
+      rtems_debugger_set_int_reg(thread, REG_ESI,    frame->esi);
+      rtems_debugger_set_int_reg(thread, REG_EDI,    frame->edi);
+      rtems_debugger_set_int_reg(thread, REG_EIP,    frame->eip);
+      rtems_debugger_set_int_reg(thread, REG_EFLAGS, frame->eflags);
+      rtems_debugger_set_int_reg(thread, REG_CS,     frame->cs);
 
       /*
        * Get the signal from the frame.
@@ -240,16 +317,16 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
       thread->signal = rtems_debugger_target_exception_to_signal(frame);
     }
     else {
-      regs[REG_EBX]    = thread->tcb->Registers.ebx;
-      regs[REG_ESI]    = thread->tcb->Registers.esi;
-      regs[REG_EDI]    = thread->tcb->Registers.edi;
-      regs[REG_EFLAGS] = thread->tcb->Registers.eflags;
-      regs[REG_ESP]    = (intptr_t) thread->tcb->Registers.esp;
-      regs[REG_EBP]    = (intptr_t) thread->tcb->Registers.ebp;
-      regs[REG_EIP]    = *((DB_UINT*) thread->tcb->Registers.esp);
-      regs[REG_EAX]    = (intptr_t) thread;
+      rtems_debugger_set_int_reg(thread, REG_EBX,    thread->tcb->Registers.ebx);
+      rtems_debugger_set_int_reg(thread, REG_ESI,    thread->tcb->Registers.esi);
+      rtems_debugger_set_int_reg(thread, REG_EDI,    thread->tcb->Registers.edi);
+      rtems_debugger_set_int_reg(thread, REG_EFLAGS, thread->tcb->Registers.eflags);
+      rtems_debugger_set_int_reg(thread, REG_ESP,    (intptr_t) thread->tcb->Registers.esp);
+      rtems_debugger_set_int_reg(thread, REG_EBP,    (intptr_t) thread->tcb->Registers.ebp);
+      rtems_debugger_set_int_reg(thread, REG_EIP,    *((DB_UINT*) thread->tcb->Registers.esp));
+      rtems_debugger_set_int_reg(thread, REG_EAX,    (intptr_t) thread);
 
-      GET_SEG_REG(CS, regs[REG_CS]);
+      rtems_debugger_set_int_reg(thread, REG_CS, get_seg_reg(REG_CS));
 
       /*
        * Blocked threads have no signal.
@@ -257,11 +334,11 @@ rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
       thread->signal = 0;
     }
 
-    GET_SEG_REG(SS, regs[REG_SS]);
-    GET_SEG_REG(DS, regs[REG_DS]);
-    GET_SEG_REG(ES, regs[REG_ES]);
-    GET_SEG_REG(FS, regs[REG_FS]);
-    GET_SEG_REG(GS, regs[REG_GS]);
+    rtems_debugger_set_int_reg(thread, REG_SS, get_seg_reg(REG_SS));
+    rtems_debugger_set_int_reg(thread, REG_DS, get_seg_reg(REG_DS));
+    rtems_debugger_set_int_reg(thread, REG_ES, get_seg_reg(REG_ES));
+    rtems_debugger_set_int_reg(thread, REG_FS, get_seg_reg(REG_FS));
+    rtems_debugger_set_int_reg(thread, REG_GS, get_seg_reg(REG_GS));
 
     thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID;
     thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
@@ -275,8 +352,6 @@ rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
 {
   if (rtems_debugger_thread_flag(thread,
                                  RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY)) {
-    uint32_t* regs = &thread->registers[0];
-
     /*
      * Only write to debugger controlled threads. Do not touch the registers
      * for threads blocked in the context switcher.
@@ -284,17 +359,17 @@ rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
     if (rtems_debugger_thread_flag(thread,
                                    RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
       CPU_Exception_frame* frame = thread->frame;
-      frame->eax    = regs[REG_EAX];
-      frame->ecx    = regs[REG_ECX];
-      frame->edx    = regs[REG_EDX];
-      frame->ebx    = regs[REG_EBX];
-      frame->esp0   = regs[REG_ESP];
-      frame->ebp    = regs[REG_EBP];
-      frame->esi    = regs[REG_ESI];
-      frame->edi    = regs[REG_EDI];
-      frame->eip    = regs[REG_EIP];
-      frame->eflags = regs[REG_EFLAGS];
-      frame->cs     = regs[REG_CS];
+      frame->eax    = rtems_debugger_get_int_reg(thread, REG_EAX);
+      frame->ecx    = rtems_debugger_get_int_reg(thread, REG_ECX);
+      frame->edx    = rtems_debugger_get_int_reg(thread, REG_EDX);
+      frame->ebx    = rtems_debugger_get_int_reg(thread, REG_EBX);
+      frame->esp0   = rtems_debugger_get_int_reg(thread, REG_ESP);
+      frame->ebp    = rtems_debugger_get_int_reg(thread, REG_EBP);
+      frame->esi    = rtems_debugger_get_int_reg(thread, REG_ESI);
+      frame->edi    = rtems_debugger_get_int_reg(thread, REG_EDI);
+      frame->eip    = rtems_debugger_get_int_reg(thread, REG_EIP);
+      frame->eflags = rtems_debugger_get_int_reg(thread, REG_EFLAGS);
+      frame->cs     = rtems_debugger_get_int_reg(thread, REG_CS);
     }
     thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
   }
@@ -307,8 +382,7 @@ rtems_debugger_target_reg_pc(rtems_debugger_thread* thread)
   int r;
   r = rtems_debugger_target_read_regs(thread);
   if (r >= 0) {
-    uint32_t* regs = &thread->registers[0];
-    return regs[REG_EIP];
+    return rtems_debugger_get_int_reg(thread, REG_EIP);
   }
   return 0;
 }
@@ -325,8 +399,7 @@ rtems_debugger_target_reg_sp(rtems_debugger_thread* thread)
   int r;
   r = rtems_debugger_target_read_regs(thread);
   if (r >= 0) {
-    uint32_t* regs = &thread->registers[0];
-    return regs[REG_ESP];
+    return rtems_debugger_get_int_reg(thread, REG_ESP);
   }
   return 0;
 }
@@ -400,6 +473,18 @@ rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame)
   return sig;
 }
 
+void
+rtems_debugger_target_exception_print(CPU_Exception_frame* frame)
+{
+  rtems_debugger_printf(" EAX = %" PRIx32 " EBX = %" PRIx32           \
+                        " ECX = %" PRIx32 " EDX = %" PRIx32 "\n",
+                        frame->eax, frame->ebx, frame->ecx, frame->edx);
+  rtems_debugger_printf(" ESI = %" PRIx32 " EDI = %" PRIx32           \
+                        " EBP = %" PRIx32 " ESP = %" PRIx32 "\n",
+                        frame->esi, frame->edi, frame->ebp, frame->esp0);
+  rtems_debugger_printf(" EIP = %" PRIx32"\n", frame->eip);
+}
+
 int
 rtems_debugger_target_hwbreak_insert(void)
 {
diff --git a/cpukit/libdebugger/rtems-debugger-server.c b/cpukit/libdebugger/rtems-debugger-server.c
index 411994d8bc..765649f131 100644
--- a/cpukit/libdebugger/rtems-debugger-server.c
+++ b/cpukit/libdebugger/rtems-debugger-server.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Chris Johns <chrisj at rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj at rtems.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,7 @@
 #define RTEMS_DEBUGGER_PRINT_PRINTK 1
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -897,7 +898,7 @@ remote_gq_thread_extra_info(uint8_t* buffer, int size)
         current = rtems_debugger_thread_current(threads);
         thread = &current[r];
         l = snprintf(buf, sizeof(buf),
-                     "%4s (%08lx), ", thread->name, thread->id);
+                     "%4s (%08" PRIx32 "), ", thread->name, thread->id);
         remote_packet_out_append_hex((const uint8_t*) buf, l);
         l = snprintf(buf, sizeof(buf),
                      "priority(c:%3d r:%3d), ",
@@ -1330,7 +1331,7 @@ remote_read_general_regs(uint8_t* buffer, int size)
     if (r >= 0) {
       remote_packet_out_reset();
       r = remote_packet_out_append_hex((const uint8_t*) &thread->registers[0],
-                                       rtems_debugger_target_reg_size());
+                                       rtems_debugger_target_reg_table_size());
       if (r >= 0)
         ok = true;
     }
@@ -1345,12 +1346,12 @@ static int
 remote_write_general_regs(uint8_t* buffer, int size)
 {
   rtems_debugger_threads* threads = rtems_debugger->threads;
-  size_t                  reg_size = rtems_debugger_target_reg_size();
+  size_t                  reg_table_size = rtems_debugger_target_reg_table_size();
   bool                    ok = false;
   int                     r;
   if (threads->selector_gen >= 0 &&
       threads->selector_gen < (int) threads->current.level &&
-      ((size - 1) / 2) == (int) reg_size) {
+      ((size - 1) / 2) == (int) reg_table_size) {
     rtems_debugger_thread* current;
     rtems_debugger_thread* thread;
     current = rtems_debugger_thread_current(threads);
@@ -1359,7 +1360,7 @@ remote_write_general_regs(uint8_t* buffer, int size)
     if (r >= 0) {
       r = rtems_debugger_remote_packet_in_hex((uint8_t*) &thread->registers[0],
                                               (const char*) &buffer[1],
-                                              reg_size);
+                                              reg_table_size);
       if (r >= 0) {
         thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
         ok = true;
@@ -1388,9 +1389,11 @@ remote_read_reg(uint8_t* buffer, int size)
       thread = &current[threads->selector_gen];
       r = rtems_debugger_target_read_regs(thread);
       if (r >= 0) {
-        const uint8_t* addr = (const uint8_t*) &thread->registers[reg];
+        const size_t   reg_size = rtems_debugger_target_reg_size(reg);
+        const size_t   reg_offset = rtems_debugger_target_reg_offset(reg);
+        const uint8_t* addr = &thread->registers[reg_offset];
         remote_packet_out_reset();
-        r = remote_packet_out_append_hex(addr, sizeof(thread->registers[0]));
+        r = remote_packet_out_append_hex(addr, reg_size);
         if (r >= 0)
           ok = true;
       }
@@ -1421,10 +1424,10 @@ remote_write_reg(uint8_t* buffer, int size)
         thread = &current[threads->selector_gen];
         r = rtems_debugger_target_read_regs(thread);
         if (r >= 0) {
-          uint8_t* addr = (uint8_t*) &thread->registers[reg];
-          r = rtems_debugger_remote_packet_in_hex(addr,
-                                                  equals + 1,
-                                                  sizeof(thread->registers[reg]));
+          const size_t reg_size = rtems_debugger_target_reg_size(reg);
+          const size_t reg_offset = rtems_debugger_target_reg_offset(reg);
+          uint8_t*     addr = &thread->registers[reg_offset];
+          r = rtems_debugger_remote_packet_in_hex(addr, equals + 1, reg_size);
           if (r == 0) {
             thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
             response = r_OK;
@@ -1505,7 +1508,7 @@ remote_single_step(uint8_t* buffer, int size)
       rtems_debugger_thread* current;
       char                   vCont_s[32];
       current = rtems_debugger_thread_current(threads);
-      snprintf(vCont_s, sizeof(vCont_s), "vCont;s:p1.%08lx;c:p1.-1",
+      snprintf(vCont_s, sizeof(vCont_s), "vCont;s:p1.%08" PRIx32 ";c:p1.-1",
                current[threads->selector_cont].id);
       return remote_v_continue((uint8_t*) vCont_s, strlen(vCont_s));
     }
@@ -1668,6 +1671,8 @@ rtems_debugger_events(rtems_task_argument arg)
 
   while (rtems_debugger_server_events_running()) {
     rtems_debugger_server_events_wait();
+    if (rtems_debugger_verbose())
+      rtems_debugger_printf("rtems-db: event woken\n");
     if (!rtems_debugger_server_events_running())
       break;
     r = rtems_debugger_thread_system_suspend();
@@ -1949,6 +1954,15 @@ rtems_debugger_start(const char*          remote,
   return 0;
 }
 
+void
+rtems_debugger_server_crash(void)
+{
+  rtems_debugger_lock();
+  rtems_debugger->server_running = false;
+  rtems_debugger_unlock();
+  rtems_debugger->remote->end(rtems_debugger->remote);
+}
+
 int
 rtems_debugger_stop(void)
 {
diff --git a/cpukit/libdebugger/rtems-debugger-target.c b/cpukit/libdebugger/rtems-debugger-target.c
index eac9498535..b2fba73113 100644
--- a/cpukit/libdebugger/rtems-debugger-target.c
+++ b/cpukit/libdebugger/rtems-debugger-target.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Chris Johns <chrisj at rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj at rtems.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -134,16 +134,36 @@ rtems_debugger_target_capabilities(void)
 size_t
 rtems_debugger_target_reg_num(void)
 {
-  if (rtems_debugger->target != NULL)
-    return rtems_debugger->target->reg_num;
+  rtems_debugger_target* target = rtems_debugger->target;
+  if (target != NULL)
+    return target->reg_num;
   return 0;
 }
 
 size_t
-rtems_debugger_target_reg_size(void)
+rtems_debugger_target_reg_size(size_t reg)
 {
-  if (rtems_debugger->target != NULL)
-    return rtems_debugger->target->reg_num * rtems_debugger->target->reg_size;
+  rtems_debugger_target* target = rtems_debugger->target;
+  if (target != NULL && reg < target->reg_num)
+    return target->reg_offset[reg + 1] - target->reg_offset[reg];
+  return 0;
+}
+
+size_t
+rtems_debugger_target_reg_offset(size_t reg)
+{
+  rtems_debugger_target* target = rtems_debugger->target;
+  if (target != NULL && reg < target->reg_num)
+    return target->reg_offset[reg];
+  return 0;
+}
+
+size_t
+rtems_debugger_target_reg_table_size(void)
+{
+  rtems_debugger_target* target = rtems_debugger->target;
+  if (target != NULL)
+    return target->reg_offset[target->reg_num];
   return 0;
 }
 
@@ -305,17 +325,23 @@ rtems_debugger_target_exception(CPU_Exception_frame* frame)
     rtems_debugger_lock();
 
     /*
-     * If the thread is the debugger recover.
+     * If the thread is in the debugger recover. If the access is from gdb
+     * continue else shutdown and let the user know.
      */
-    if (tid == rtems_debugger->server_task) {
-      if (rtems_debugger->target->memory_access) {
-        target_printk("[} server access fault\n");
-        rtems_debugger->target->memory_access = true;
-        rtems_debugger_unlock();
+    if (tid == rtems_debugger->server_task ||
+        tid == rtems_debugger->events_task) {
+      bool memory_access = rtems_debugger_target_is_memory_access();
+      rtems_debugger_unlock();
+      /*
+       * Has GDB has asked us to write to an address?
+       */
+      if (memory_access) {
+        target_printk("[} server fault: memory access\n");
         longjmp(rtems_debugger->target->access_return, -1);
       }
-      target_printk("[} server exception\n");
-      rtems_debugger_unlock();
+      rtems_debugger_printf("rtems-db: server exception (report)\n");
+      rtems_debugger_target_exception_print(frame);
+      rtems_debugger_server_crash();
       return rtems_debugger_target_exc_cascade;
     }
 
@@ -332,7 +358,7 @@ rtems_debugger_target_exception(CPU_Exception_frame* frame)
          *        the contents of the instruction, step then return the
          *        swbreak's contents.
          */
-        target_printk("[} tid:%08lx: excluded\n", tid);
+        target_printk("[} tid:%08" PRIx32 ": excluded\n", tid);
         rtems_debugger_unlock();
         return rtems_debugger_target_exc_cascade;
       }
@@ -346,12 +372,12 @@ rtems_debugger_target_exception(CPU_Exception_frame* frame)
     if (stepper != NULL) {
       stepper->thread->frame = frame;
       rtems_debugger_target_thread_stepping(stepper->thread);
-      target_printk("[} tid:%08lx: stepping\n", tid);
+      target_printk("[} tid:%08" PRIx32 ": stepping\n", tid);
       rtems_debugger_unlock();
       return rtems_debugger_target_exc_step;
     }
 
-    target_printk("[} tid:%08lx: suspending\n", tid);
+    target_printk("[} tid:%08" PRIx32 ": suspending\n", tid);
 
     /*
      * Initialise the target exception data and queue ready for the debugger
@@ -381,7 +407,7 @@ rtems_debugger_target_exception(CPU_Exception_frame* frame)
      */
     rtems_debugger_unlock();
 
-    target_printk("[} tid:%08lx: resuming\n", tid);
+    target_printk("[} tid:%08" PRIx32 ": resuming\n", tid);
 
     return rtems_debugger_target_exc_consumed;
   }
@@ -439,3 +465,9 @@ rtems_debugger_target_end_memory_access(void)
 {
   rtems_debugger->target->memory_access = false;
 }
+
+bool
+rtems_debugger_target_is_memory_access(void)
+{
+  return rtems_debugger->target->memory_access;
+}
diff --git a/cpukit/libdebugger/rtems-debugger-target.h b/cpukit/libdebugger/rtems-debugger-target.h
index 0e1156c889..f2abbe5fd3 100644
--- a/cpukit/libdebugger/rtems-debugger-target.h
+++ b/cpukit/libdebugger/rtems-debugger-target.h
@@ -85,11 +85,15 @@ typedef struct rtems_debugger_target_swbreak {
 
 /**
  * The target data.
+ *
+ * reg_offset: Table of size_t offset of a register in the register
+ *             table. The table has one more entry than reg_num where
+ *             the last entry is the size of the register table.
  */
 typedef struct rtems_debugger_target {
   int                  capabilities;     /*<< The capabilities to report. */
   size_t               reg_num;          /*<< The number of registers. */
-  size_t               reg_size;         /*<< The size of a register. */
+  const size_t*        reg_offset;       /*<< The reg offsettable, len = reg_num + 1. */
   const uint8_t*       breakpoint;       /*<< The breakpoint instruction(s). */
   size_t               breakpoint_size;  /*<< The breakpoint size. */
   rtems_debugger_block swbreaks;         /*<< The software breakpoint block. */
@@ -133,9 +137,19 @@ extern uint32_t rtems_debugger_target_capabilities(void);
 extern size_t rtems_debugger_target_reg_num(void);
 
 /**
- * Return the size of the regisers in bytes.
+ * Return the offset of a register in the register table.
+ */
+extern size_t rtems_debugger_target_reg_size(size_t reg);
+
+/**
+ * Return the offset of a register in the register table.
+ */
+extern size_t rtems_debugger_target_reg_offset(size_t reg);
+
+/**
+ * Return the size of register table.
  */
-extern size_t rtems_debugger_target_reg_size(void);
+extern size_t rtems_debugger_target_reg_table_size(void);
 
 /**
  * Read the regosters.
@@ -177,6 +191,11 @@ extern int rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread);
  */
 extern int rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame);
 
+/**
+ * Print the target exception registers.
+ */
+extern void rtems_debugger_target_exception_print(CPU_Exception_frame* frame);
+
 /**
  * Software breakpoints. These are also referred to as memory breakpoints.
  */
@@ -245,6 +264,11 @@ extern int rtems_debugger_target_start_memory_access(void);
  */
 extern void rtems_debugger_target_end_memory_access(void);
 
+/**
+ * Is this a target memory access?
+ */
+extern bool rtems_debugger_target_is_memory_access(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/cpukit/libdebugger/rtems-debugger-threads.c b/cpukit/libdebugger/rtems-debugger-threads.c
index bc6e952b11..ef34e086d5 100644
--- a/cpukit/libdebugger/rtems-debugger-threads.c
+++ b/cpukit/libdebugger/rtems-debugger-threads.c
@@ -25,6 +25,7 @@
  */
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdlib.h>
 #include <stdio.h>
 
@@ -85,7 +86,7 @@ rtems_debugger_thread_create(void)
 
   r = rtems_debugger_block_create(&threads->registers,
                                   RTEMS_DEBUGGER_THREAD_BLOCK_SIZE,
-                                  rtems_debugger_target_reg_size());
+                                  rtems_debugger_target_reg_table_size());
   if (r < 0) {
     rtems_debugger_thread_free(threads);
     free(threads);
@@ -209,7 +210,7 @@ snapshot_thread(rtems_tcb* tcb, void* arg)
   }
   else {
     rtems_debugger_thread* current;
-    DB_UINT*               registers;
+    uint8_t*               registers;
     rtems_debugger_thread* thread;
     int                    r;
 
@@ -262,7 +263,7 @@ snapshot_thread(rtems_tcb* tcb, void* arg)
       rtems_status_code sc;
       sc = rtems_task_suspend(id);
       if (sc != RTEMS_SUCCESSFUL && sc != RTEMS_ALREADY_SUSPENDED) {
-        rtems_debugger_printf("error: rtems-db: thread: suspend: %08lx: %s\n",
+        rtems_debugger_printf("error: rtems-db: thread: suspend: %08" PRIx32 ": %s\n",
                               id, rtems_status_text(sc));
         r = -1;
       }
@@ -274,7 +275,7 @@ snapshot_thread(rtems_tcb* tcb, void* arg)
     rtems_debugger_target_read_regs(thread);
 
     if (rtems_debugger_server_flag(RTEMS_DEBUGGER_FLAG_VERBOSE))
-      rtems_debugger_printf("rtems-db: sys: thd: %08lx: signal: %d\n",
+      rtems_debugger_printf("rtems-db: sys: thd: %08" PRIx32 ": signal: %d\n",
                             id, thread->signal);
 
     /*
@@ -380,7 +381,7 @@ rtems_debugger_thread_system_resume(bool detaching)
             }
           }
           if (rtems_debugger_verbose())
-            rtems_debugger_printf("rtems-db: sys:    : resume: 0x%08lx\n",
+            rtems_debugger_printf("rtems-db: sys:    : resume: 0x%08" PRIx32 "\n",
                                   thread->id);
           if (rtems_debugger_thread_flag(thread,
                                          RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
@@ -388,7 +389,7 @@ rtems_debugger_thread_system_resume(bool detaching)
           } else {
               sc = rtems_task_resume(thread->id);
               if (sc != RTEMS_SUCCESSFUL) {
-                  rtems_debugger_printf("error: rtems-db: thread: resume: %08lx: %s\n",
+                  rtems_debugger_printf("error: rtems-db: thread: resume: %08" PRIx32 ": %s\n",
                                         thread->id, rtems_status_text(sc));
               }
           }
diff --git a/cpukit/libdebugger/rtems-debugger-threads.h b/cpukit/libdebugger/rtems-debugger-threads.h
index 8beac1a429..200dbbe1c7 100644
--- a/cpukit/libdebugger/rtems-debugger-threads.h
+++ b/cpukit/libdebugger/rtems-debugger-threads.h
@@ -90,7 +90,7 @@ typedef struct rtems_debugger_thread
   Thread_Control* tcb;
   rtems_id        id;
   int             cpu;
-  DB_UINT*        registers;
+  uint8_t*        registers;
   int             signal;
   void*           frame;
 } rtems_debugger_thread;
@@ -234,7 +234,7 @@ rtems_debugger_thread_current(rtems_debugger_threads* threads)
 /**
  * Get the registers.
  */
-static inline DB_UINT*
+static inline uint8_t*
 rtems_debugger_thread_registers(rtems_debugger_threads* threads)
 {
   return threads->registers.block;
-- 
2.19.1



More information about the devel mailing list