- rename flash_init and flash_erase to flash_init_drivers and flash_erase_address_range - stops conflicts with redboot. Thanks Øyvind Harboe

- gdb connection not dropped if we fail to allocate memory in query packets



git-svn-id: svn://svn.berlios.de/openocd/trunk@249 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
ntfreak 2008-01-09 15:58:01 +00:00
parent 2e01a1ad19
commit 0160320060
4 changed files with 56 additions and 40 deletions

View File

@ -90,7 +90,7 @@ int flash_register_commands(struct command_context_s *cmd_ctx)
return ERROR_OK; return ERROR_OK;
} }
int flash_init(struct command_context_s *cmd_ctx) int flash_init_drivers(struct command_context_s *cmd_ctx)
{ {
if (flash_banks) if (flash_banks)
{ {
@ -398,7 +398,7 @@ int handle_flash_erase_address_command(struct command_context_s *cmd_ctx, char *
duration_start_measure(&duration); duration_start_measure(&duration);
if ((retval = flash_erase(target, address, length)) != ERROR_OK) if ((retval = flash_erase_address_range(target, address, length)) != ERROR_OK)
{ {
switch (retval) switch (retval)
{ {
@ -801,7 +801,7 @@ flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
} }
/* erase given flash region, selects proper bank according to target and address */ /* erase given flash region, selects proper bank according to target and address */
int flash_erase(target_t *target, u32 addr, u32 length) int flash_erase_address_range(target_t *target, u32 addr, u32 length)
{ {
flash_bank_t *c; flash_bank_t *c;
int first = -1; int first = -1;
@ -977,7 +977,7 @@ int flash_write(target_t *target, image_t *image, u32 *written, char **error_str
if (erase) if (erase)
{ {
/* calculate and erase sectors */ /* calculate and erase sectors */
retval = flash_erase( target, run_address, run_size ); retval = flash_erase_address_range( target, run_address, run_size );
} }
if (retval == ERROR_OK) if (retval == ERROR_OK)

View File

@ -64,9 +64,9 @@ typedef struct flash_bank_s
} flash_bank_t; } flash_bank_t;
extern int flash_register_commands(struct command_context_s *cmd_ctx); extern int flash_register_commands(struct command_context_s *cmd_ctx);
extern int flash_init(struct command_context_s *cmd_ctx); extern int flash_init_drivers(struct command_context_s *cmd_ctx);
extern int flash_erase(target_t *target, u32 addr, u32 length); extern int flash_erase_address_range(target_t *target, u32 addr, u32 length);
extern int flash_write(target_t *target, image_t *image, u32 *written, char **error, int *failed, int erase); extern int flash_write(target_t *target, image_t *image, u32 *written, char **error, int *failed, int erase);
extern void flash_set_dirty(void); extern void flash_set_dirty(void);

View File

@ -117,7 +117,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
DEBUG("target init complete"); DEBUG("target init complete");
if (flash_init(cmd_ctx) != ERROR_OK) if (flash_init_drivers(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE; return EXIT_FAILURE;
DEBUG("flash init complete"); DEBUG("flash init complete");

View File

@ -289,7 +289,8 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
if ((retval = gdb_get_char(connection, &character)) != ERROR_OK) if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
return retval; return retval;
if (character == '#') break; if (character == '#')
break;
if (character == '}') if (character == '}')
{ {
@ -532,30 +533,33 @@ int gdb_last_signal_packet(connection_t *connection, target_t *target, char* pac
return ERROR_OK; return ERROR_OK;
} }
void gdb_str_to_target(target_t *target, char *str, char *tstr) /* Convert register to string of bits. NB! The # of bits in the
* register might be non-divisible by 8(a byte), in which
* case an entire byte is shown. */
void gdb_str_to_target(target_t *target, char *tstr, reg_t *reg)
{ {
int str_len = strlen(str); static const char *DIGITS = "0123456789abcdef";
int i; int i;
if (str_len % 2) u8 *buf;
{ int buf_len;
ERROR("BUG: gdb value with uneven number of characters encountered: %s", str); buf = reg->value;
exit(-1); buf_len = CEIL(reg->size, 8);
}
if (target->endianness == TARGET_LITTLE_ENDIAN) if (target->endianness == TARGET_LITTLE_ENDIAN)
{ {
for (i = 0; i < str_len; i+=2) for (i = 0; i < buf_len; i++)
{ {
tstr[str_len - i - 1] = str[i + 1]; tstr[i*2] = DIGITS[(buf[i]>>4) & 0xf];
tstr[str_len - i - 2] = str[i]; tstr[i*2+1] = DIGITS[buf[i]&0xf];
} }
} }
else else
{ {
for (i = 0; i < str_len; i++) for (i = 0; i < buf_len; i++)
{ {
tstr[i] = str[i]; tstr[(buf_len-1-i)*2] = DIGITS[(buf[i]>>4)&0xf];
tstr[(buf_len-1-i)*2+1] = DIGITS[buf[i]&0xf];
} }
} }
} }
@ -598,7 +602,9 @@ int gdb_get_registers_packet(connection_t *connection, target_t *target, char* p
char *reg_packet_p; char *reg_packet_p;
int i; int i;
#ifdef _DEBUG_GDB_IO_
DEBUG("-"); DEBUG("-");
#endif
if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK) if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
{ {
@ -624,16 +630,18 @@ int gdb_get_registers_packet(connection_t *connection, target_t *target, char* p
for (i = 0; i < reg_list_size; i++) for (i = 0; i < reg_list_size; i++)
{ {
char *hex_buf = buf_to_str(reg_list[i]->value, reg_list[i]->size, 16); gdb_str_to_target(target, reg_packet_p, reg_list[i]);
DEBUG("hex_buf: %s", hex_buf);
gdb_str_to_target(target, hex_buf, reg_packet_p);
reg_packet_p += CEIL(reg_list[i]->size, 8) * 2; reg_packet_p += CEIL(reg_list[i]->size, 8) * 2;
free(hex_buf);
} }
reg_packet_p = strndup(reg_packet, CEIL(reg_packet_size, 8) * 2); #ifdef _DEBUG_GDB_IO_
DEBUG("reg_packet: %s", reg_packet_p); {
free(reg_packet_p); char *reg_packet_p;
reg_packet_p = strndup(reg_packet, CEIL(reg_packet_size, 8) * 2);
DEBUG("reg_packet: %s", reg_packet_p);
free(reg_packet_p);
}
#endif
gdb_put_packet(connection, reg_packet, CEIL(reg_packet_size, 8) * 2); gdb_put_packet(connection, reg_packet, CEIL(reg_packet_size, 8) * 2);
free(reg_packet); free(reg_packet);
@ -651,7 +659,9 @@ int gdb_set_registers_packet(connection_t *connection, target_t *target, char *p
int retval; int retval;
char *packet_p; char *packet_p;
#ifdef _DEBUG_GDB_IO_
DEBUG("-"); DEBUG("-");
#endif
/* skip command character */ /* skip command character */
packet++; packet++;
@ -723,9 +733,10 @@ int gdb_get_register_packet(connection_t *connection, target_t *target, char *pa
reg_t **reg_list; reg_t **reg_list;
int reg_list_size; int reg_list_size;
int retval; int retval;
char *hex_buf;
#ifdef _DEBUG_GDB_IO_
DEBUG("-"); DEBUG("-");
#endif
if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK) if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
{ {
@ -749,15 +760,12 @@ int gdb_get_register_packet(connection_t *connection, target_t *target, char *pa
reg_packet = malloc(CEIL(reg_list[reg_num]->size, 8) * 2); reg_packet = malloc(CEIL(reg_list[reg_num]->size, 8) * 2);
hex_buf = buf_to_str(reg_list[reg_num]->value, reg_list[reg_num]->size, 16); gdb_str_to_target(target, reg_packet, reg_list[reg_num]);
gdb_str_to_target(target, hex_buf, reg_packet);
gdb_put_packet(connection, reg_packet, CEIL(reg_list[reg_num]->size, 8) * 2); gdb_put_packet(connection, reg_packet, CEIL(reg_list[reg_num]->size, 8) * 2);
free(reg_list); free(reg_list);
free(reg_packet); free(reg_packet);
free(hex_buf);
return ERROR_OK; return ERROR_OK;
} }
@ -1240,13 +1248,13 @@ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, .
* Need minimum 2 bytes to fit 1 char and 0 terminator. */ * Need minimum 2 bytes to fit 1 char and 0 terminator. */
*size = *size * 2 + 2; *size = *size * 2 + 2;
char *t=*xml; char *t = *xml;
*xml = realloc(*xml, *size); *xml = realloc(*xml, *size);
if (*xml == NULL) if (*xml == NULL)
{ {
if (t) if (t)
free(t); free(t);
*retval=ERROR_SERVER_REMOTE_CLOSED; *retval = ERROR_SERVER_REMOTE_CLOSED;
return; return;
} }
} }
@ -1309,6 +1317,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
cmd[i] = tmp; cmd[i] = tmp;
} }
cmd[(packet_size - 6)/2] = 0x0; cmd[(packet_size - 6)/2] = 0x0;
target_call_timer_callbacks();
command_run_line(cmd_ctx, cmd); command_run_line(cmd_ctx, cmd);
free(cmd); free(cmd);
} }
@ -1363,15 +1372,21 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
char *buffer = NULL; char *buffer = NULL;
int pos = 0; int pos = 0;
int size = 0; int size = 0;
xml_printf(&retval, &buffer, &pos, &size, xml_printf(&retval, &buffer, &pos, &size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-", "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-",
(GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-'); (GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-');
if (buffer!=NULL)
if (retval != ERROR_OK)
{ {
gdb_put_packet(connection, buffer, strlen(buffer)); gdb_send_error(connection, 01);
free(buffer); return ERROR_OK;
} }
return retval;
gdb_put_packet(connection, buffer, strlen(buffer));
free(buffer);
return ERROR_OK;
} }
else if (strstr(packet, "qXfer:memory-map:read::")) else if (strstr(packet, "qXfer:memory-map:read::"))
{ {
@ -1533,7 +1548,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM); target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM);
/* perform erase */ /* perform erase */
if ((result = flash_erase(gdb_service->target, addr, length)) != ERROR_OK) if ((result = flash_erase_address_range(gdb_service->target, addr, length)) != ERROR_OK)
{ {
/* GDB doesn't evaluate the actual error number returned, /* GDB doesn't evaluate the actual error number returned,
* treat a failed erase as an I/O error * treat a failed erase as an I/O error
@ -1598,7 +1613,8 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
/* disable gdb output while programming */ /* disable gdb output while programming */
gdb_connection->output_disable = 1; gdb_connection->output_disable = 1;
/* process the flashing buffer */ /* process the flashing buffer. No need to erase as GDB
* always issues a vFlashErase first. */
if ((result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, &error_str, NULL, 0)) != ERROR_OK) if ((result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, &error_str, NULL, 0)) != ERROR_OK)
{ {
if (result == ERROR_FLASH_DST_OUT_OF_BANK) if (result == ERROR_FLASH_DST_OUT_OF_BANK)