#include "breakpoints.h"
#include "flash.h"
#include "target_request.h"
+#include "configuration.h"
#include <string.h>
#include <errno.h>
int gdb_use_memory_map = 0;
int gdb_flash_program = 0;
+/* if set, data aborts cause an error to be reported in memory read packets
+ * see the code in gdb_read_memory_packet() for further explanations */
+int gdb_report_data_abort = 0;
+
int gdb_last_signal(target_t *target)
{
switch (target->debug_reason)
int gdb_output(struct command_context_s *context, char* line)
{
/* this will be dumped to the log and also sent as an O packet if possible */
- ERROR(line);
+ USER(line);
return ERROR_OK;
}
if (target->gdb_program_script)
{
- script = fopen(target->gdb_program_script, "r");
+ script = open_file_from_path(cmd_ctx, target->gdb_program_script, "r");
if (!script)
{
ERROR("couldn't open script file %s", target->gdb_program_script);
DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
- switch (len)
- {
- case 4:
- if ((addr % 4) == 0)
- retval = target->type->read_memory(target, addr, 4, 1, buffer);
- else
- retval = target->type->read_memory(target, addr, 1, len, buffer);
- break;
- case 2:
- if ((addr % 2) == 0)
- retval = target->type->read_memory(target, addr, 2, 1, buffer);
- else
- retval = target->type->read_memory(target, addr, 1, len, buffer);
- break;
- case 3:
- case 1:
- retval = target->type->read_memory(target, addr, 1, len, buffer);
- break;
- /* handle bulk reads */
- default:
- retval = target_read_buffer(target, addr, len, buffer);
- break;
- }
+ retval = target_read_buffer(target, addr, len, buffer);
-#if 0
- if (retval == ERROR_TARGET_DATA_ABORT)
+ if ((retval == ERROR_TARGET_DATA_ABORT) && (!gdb_report_data_abort))
{
/* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
* At some point this might be fixed in GDB, in which case this code can be removed.
+ *
+ * OpenOCD developers are acutely aware of this problem, but there is nothing
+ * gained by involving the user in this problem that hopefully will get resolved
+ * eventually
+ *
* http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
+ *
+ * For now, the default is to fix up things to make current GDB versions work.
+ * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command.
*/
memset(buffer, 0, len);
retval = ERROR_OK;
}
-#endif
if (retval == ERROR_OK)
{
buffer[i] = tmp;
}
- retval = ERROR_OK;
- switch (len)
- {
- /* handle sized writes */
- case 4:
- if ((addr % 4) == 0)
- retval = target->type->write_memory(target, addr, 4, 1, buffer);
- else
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- case 2:
- if ((addr % 2) == 0)
- retval = target->type->write_memory(target, addr, 2, 1, buffer);
- else
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- case 3:
- case 1:
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- /* handle bulk writes */
- default:
- retval = target_write_buffer(target, addr, len, buffer);
- break;
- }
+ retval = target_write_buffer(target, addr, len, buffer);
if (retval == ERROR_OK)
{
u32 addr = 0;
u32 len = 0;
- u8 *buffer;
int retval;
/* skip command character */
}
retval = ERROR_OK;
- if( len ) {
-
- buffer = malloc(len);
-
+ if (len)
+ {
DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
- memcpy( buffer, separator, len );
-
- switch (len)
- {
- case 4:
- if ((addr % 4) == 0)
- retval = target->type->write_memory(target, addr, 4, 1, buffer);
- else
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- case 2:
- if ((addr % 2) == 0)
- retval = target->type->write_memory(target, addr, 2, 1, buffer);
- else
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- case 3:
- case 1:
- retval = target->type->write_memory(target, addr, 1, len, buffer);
- break;
- default:
- retval = target_write_buffer(target, addr, len, buffer);
- break;
- }
-
- free(buffer);
+ retval = target_write_buffer(target, addr, len, (u8*)separator);
}
if (retval == ERROR_OK)
}
}
-static int decode_xfer_read (char *buf, char **annex, int *ofs, unsigned int *len)
+static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len)
{
char *separator;
if (packet_size > 5)
{
int retval;
- u8 gdb_reply[10];
+ char gdb_reply[10];
char *separator;
u32 checksum;
u32 addr = 0;
int retval = ERROR_OK;
int offset;
- int length;
+ unsigned int length;
char *annex;
/* skip command character */
packet += 20;
- if (decode_xfer_read( packet, &annex, &offset, &length ) < 0)
+ if (decode_xfer_read(packet, &annex, &offset, &length) < 0)
{
gdb_send_error(connection, 01);
return ERROR_OK;
return ERROR_OK;
}
+int handle_gdb_report_data_abort_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ if (argc == 1)
+ {
+ if (strcmp(args[0], "enable") == 0)
+ {
+ gdb_report_data_abort = 1;
+ return ERROR_OK;
+ }
+ else if (strcmp(args[0], "disable") == 0)
+ {
+ gdb_report_data_abort = 0;
+ return ERROR_OK;
+ }
+ }
+
+ WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
+ return ERROR_OK;
+}
+
int gdb_register_commands(command_context_t *command_context)
{
register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
COMMAND_CONFIG, "");
register_command(command_context, NULL, "gdb_flash_program", handle_gdb_flash_program_command,
COMMAND_CONFIG, "");
+ register_command(command_context, NULL, "gdb_report_data_abort", handle_gdb_report_data_abort_command,
+ COMMAND_CONFIG, "");
return ERROR_OK;
}