#include <jtag/jtag.h>
+/**
+ * @file
+ * GDB server implementation.
+ *
+ * This implements the GDB Remote Serial Protocol, over TCP connections,
+ * giving GDB access to the JTAG or other hardware debugging facilities
+ * found in most modern embedded processors.
+ */
+
/* private connection data for GDB */
struct gdb_connection
{
extern int gdb_error(struct connection *connection, int retval);
static unsigned short gdb_port = 3333;
static unsigned short gdb_port_next = 0;
-static const char *DIGITS = "0123456789abcdef";
+static const char DIGITS[16] = "0123456789abcdef";
static void gdb_log_callback(void *priv, const char *file, unsigned line,
const char *function, const char *string);
{
int type;
enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
- enum watchpoint_rw wp_type;
+ enum watchpoint_rw wp_type = WPT_READ /* dummy init to avoid warning */;
uint32_t address;
uint32_t size;
char *separator;
wp_type = WPT_READ;
else if (type == 4) /* access watchpoint */
wp_type = WPT_ACCESS;
+ else
+ {
+ LOG_ERROR("invalid gdb watch/breakpoint type(%d), dropping connection", type);
+ return ERROR_SERVER_REMOTE_CLOSED;
+ }
+
if (gdb_breakpoint_override && ((bp_type == BKPT_SOFT)||(bp_type == BKPT_HARD)))
{
{
if (packet[0] == 'Z')
{
- if ((retval = watchpoint_add(target, address, size, type-2, 0, 0xffffffffu)) != ERROR_OK)
+ if ((retval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu)) != ERROR_OK)
{
if ((retval = gdb_error(connection, retval)) != ERROR_OK)
return retval;
flash_set_dirty();
/* perform any target specific operations before the erase */
- target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_START);
- result = flash_erase_address_range(gdb_service->target, addr, length);
- target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_END);
+ target_call_event_callbacks(gdb_service->target,
+ TARGET_EVENT_GDB_FLASH_ERASE_START);
+
+ /* vFlashErase:addr,length messages require region start and
+ * end to be "block" aligned ... if padding is ever needed,
+ * GDB will have become dangerously confused.
+ */
+ result = flash_erase_address_range(gdb_service->target,
+ false, addr, length);
+
+ /* perform any target specific operations after the erase */
+ target_call_event_callbacks(gdb_service->target,
+ TARGET_EVENT_GDB_FLASH_ERASE_END);
/* perform erase */
if (result != ERROR_OK)
static const struct command_registration gdb_command_handlers[] = {
{
.name = "gdb_sync",
- .handler = &handle_gdb_sync_command,
+ .handler = handle_gdb_sync_command,
.mode = COMMAND_ANY,
.help = "next stepi will return immediately allowing "
"GDB to fetch register state without affecting "
},
{
.name = "gdb_port",
- .handler = &handle_gdb_port_command,
- .mode = COMMAND_CONFIG,
- .help = "daemon configuration command gdb_port",
- .usage = "<port>",
+ .handler = handle_gdb_port_command,
+ .mode = COMMAND_ANY,
+ .help = "Display or specify base port on which to listen "
+ "for incoming GDB connections. "
+ "No arguments reports GDB port; zero disables.",
+ .usage = "[port_num]",
},
{
.name = "gdb_memory_map",
- .handler = &handle_gdb_memory_map_command,
+ .handler = handle_gdb_memory_map_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable memory map",
- .usage = "enable|disable"
+ .usage = "('enable'|'disable')"
},
{
.name = "gdb_flash_program",
- .handler = &handle_gdb_flash_program_command,
+ .handler = handle_gdb_flash_program_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable flash program",
- .usage = "enable|disable"
+ .usage = "('enable'|'disable')"
},
{
.name = "gdb_report_data_abort",
- .handler = &handle_gdb_report_data_abort_command,
+ .handler = handle_gdb_report_data_abort_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting data aborts",
- .usage = "enable|disable"
+ .usage = "('enable'|'disable')"
},
{
.name = "gdb_breakpoint_override",
- .handler = &handle_gdb_breakpoint_override_command,
- .mode = COMMAND_EXEC,
- .help = "force type of breakpoint "
- "used by gdb 'break' commands.",
- .usage = "hard|soft|disable",
+ .handler = handle_gdb_breakpoint_override_command,
+ .mode = COMMAND_ANY,
+ .help = "Display or specify type of breakpoint "
+ "to be used by gdb 'break' commands.",
+ .usage = "('hard'|'soft'|'disable')"
},
COMMAND_REGISTRATION_DONE
};