summaryrefslogtreecommitdiffstats
path: root/cpukit/libdebugger
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2019-04-08 13:17:08 +1000
committerChris Johns <chrisj@rtems.org>2019-04-09 15:02:24 +1000
commit2c09b71faf4c476cf76476dc5926f0095eb6fdcd (patch)
tree00e4102eb5282055c568e2a8e0a96f4d7c170065 /cpukit/libdebugger
parentdoxygen: Update _Objects_Build_name() (diff)
downloadrtems-2c09b71faf4c476cf76476dc5926f0095eb6fdcd.tar.bz2
libdebugger: Use an offset table to format GDB `g` packets.
Adding support for a register offset table lets FPU registers be supported if added to the backend. Closes #3733.
Diffstat (limited to 'cpukit/libdebugger')
-rw-r--r--cpukit/libdebugger/rtems-debugger-arm.c281
-rw-r--r--cpukit/libdebugger/rtems-debugger-i386.c209
-rw-r--r--cpukit/libdebugger/rtems-debugger-server.c77
-rw-r--r--cpukit/libdebugger/rtems-debugger-target.c70
-rw-r--r--cpukit/libdebugger/rtems-debugger-target.h30
-rw-r--r--cpukit/libdebugger/rtems-debugger-threads.c15
-rw-r--r--cpukit/libdebugger/rtems-debugger-threads.h4
7 files changed, 472 insertions, 214 deletions
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@rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj@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,9 +140,61 @@
#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.
*/
#if defined(ARM_MULTILIB_ARCH_V4)
@@ -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.
@@ -84,6 +78,39 @@
#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.
*/
#define TARGET_BKPT 0xcc
@@ -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..298bb95989 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@rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj@rtems.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,9 +25,9 @@
*/
#define RTEMS_DEBUGGER_VERBOSE_LOCK 0
-#define RTEMS_DEBUGGER_PRINT_PRINTK 1
#include <errno.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
@@ -84,9 +84,7 @@ rtems_debugger_server* rtems_debugger;
* Print lock ot make the prints sequential. This is to debug the debugger in
* SMP.
*/
-#if RTEMS_DEBUGGER_PRINT_PRINTK
RTEMS_INTERRUPT_LOCK_DEFINE(static, printk_lock, "printk_lock")
-#endif
void
rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context)
@@ -103,17 +101,13 @@ rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context)
int
rtems_debugger_clean_printf(const char* format, ...)
{
- int len;
- va_list ap;
+ rtems_interrupt_lock_context lock_context;
+ int len;
+ va_list ap;
va_start(ap, format);
- if (RTEMS_DEBUGGER_PRINT_PRINTK) {
- rtems_interrupt_lock_context lock_context;
- rtems_debugger_printk_lock(&lock_context);
- len = vprintk(format, ap);
- rtems_debugger_printk_unlock(&lock_context);
- }
- else
- len = rtems_vprintf(&rtems_debugger->printer, format, ap);
+ rtems_debugger_printk_lock(&lock_context);
+ len = vprintk(format, ap);
+ rtems_debugger_printk_unlock(&lock_context);
va_end(ap);
return len;
}
@@ -121,18 +115,14 @@ rtems_debugger_clean_printf(const char* format, ...)
int
rtems_debugger_printf(const char* format, ...)
{
- int len;
- va_list ap;
+ rtems_interrupt_lock_context lock_context;
+ int len;
+ va_list ap;
va_start(ap, format);
- if (RTEMS_DEBUGGER_PRINT_PRINTK) {
- rtems_interrupt_lock_context lock_context;
- rtems_debugger_printk_lock(&lock_context);
- printk("[CPU:%d] ", (int) _SMP_Get_current_processor ());
- len = vprintk(format, ap);
- rtems_debugger_printk_unlock(&lock_context);
- }
- else
- len = rtems_vprintf(&rtems_debugger->printer, format, ap);
+ rtems_debugger_printk_lock(&lock_context);
+ printk("[CPU:%d] ", (int) _SMP_Get_current_processor ());
+ len = vprintk(format, ap);
+ rtems_debugger_printk_unlock(&lock_context);
va_end(ap);
return len;
}
@@ -897,7 +887,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 +1320,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 +1335,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 +1349,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 +1378,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 +1413,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 +1497,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 +1660,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 +1943,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..e4951701e9 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@rtems.org>.
+ * Copyright (c) 2016-2019 Chris Johns <chrisj@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,12 +407,12 @@ 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;
}
- target_printk("[} cascade, in interrupt\n");
+ rtems_debugger_printf("rtems-db: exception in an interrupt, cascading\n");
return rtems_debugger_target_exc_cascade;
}
@@ -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.
@@ -178,6 +192,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.
*/
extern int rtems_debugger_target_swbreak_control(bool insert,
@@ -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..6a9d6a4bb2 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;
@@ -229,7 +230,7 @@ snapshot_thread(rtems_tcb* tcb, void* arg)
thread = &current[threads->current.level++];
thread->registers =
- &registers[threads->registers.level++ * rtems_debugger_target_reg_num()];
+ &registers[threads->registers.level++ * rtems_debugger_target_reg_table_size()];
thread->tcb = tcb;
thread->id = id;
@@ -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;