aboutsummaryrefslogtreecommitdiff
path: root/src/gdb_main.c
diff options
context:
space:
mode:
authorMike Smith2011-11-25 17:07:46 -0800
committerMike Smith2011-11-25 17:07:46 -0800
commitffda30f393cd72b6cfec21673abdee25aeaf2ee3 (patch)
treece6815b84780256e26cfbe932d4bdb415ea897b4 /src/gdb_main.c
parent8babb37472a70d8f3f4e4f8325f4ecc0af5a587a (diff)
Add support for a more comprehensive target description, including the additional v7m registers.
This doesn't work with vanilla gdb, as for reasons unknown said vanilla gdb doesn't support XML target descriptions queried from the remote. Add code to the fault unwinder to deal with the stack alignment fixup and FP registers. Avoid saving/restoring registers that don't get trashed.
Diffstat (limited to 'src/gdb_main.c')
-rw-r--r--src/gdb_main.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/src/gdb_main.c b/src/gdb_main.c
index e890999..0655d63 100644
--- a/src/gdb_main.c
+++ b/src/gdb_main.c
@@ -56,8 +56,6 @@ static unsigned char pbuf[BUF_SIZE];
static void handle_q_packet(char *packet, int len);
static void handle_v_packet(char *packet, int len);
-uint32_t arm_regs[16];
-
void
gdb_main(void)
{
@@ -74,9 +72,10 @@ gdb_main(void)
switch(pbuf[0]) {
/* Implementation of these is mandatory! */
case 'g': { /* 'g': Read general registers */
+ uint32_t arm_regs[cur_target->regs_size];
ERROR_IF_NO_TARGET();
target_regs_read(cur_target, (void*)arm_regs);
- gdb_putpacket(hexify(pbuf, (void*)arm_regs, sizeof(arm_regs)), sizeof(arm_regs)*2);
+ gdb_putpacket(hexify(pbuf, (void*)arm_regs, cur_target->regs_size), cur_target->regs_size * 2);
break;
}
case 'm': { /* 'm addr,len': Read len bytes from addr */
@@ -98,13 +97,14 @@ gdb_main(void)
free(mem);
break;
}
- case 'G': /* 'G XX': Write general registers */
+ case 'G': { /* 'G XX': Write general registers */
+ uint32_t arm_regs[cur_target->regs_size];
ERROR_IF_NO_TARGET();
unhexify((void*)arm_regs, &pbuf[1], cur_target->regs_size);
target_regs_write(cur_target, arm_regs);
gdb_putpacket("OK", 2);
break;
-
+ }
case 'M': { /* 'M addr,len:XX': Write len bytes to addr */
unsigned long addr, len;
int hex;
@@ -292,6 +292,27 @@ gdb_main(void)
}
}
+static void
+handle_q_string_reply(const char *str, const char *param)
+{
+ unsigned long addr, len;
+
+ if (sscanf(param, "%08lX,%08lX", &addr, &len) != 2) {
+ gdb_putpacketz("E01");
+ return;
+ }
+ if (addr < strlen (str)) {
+ uint8_t reply[len+2];
+ reply[0] = 'm';
+ strncpy (reply + 1, &str[addr], len);
+ if(len > strlen(&str[addr]))
+ len = strlen(&str[addr]);
+ gdb_putpacket(reply, len + 1);
+ } else if (addr == strlen (str)) {
+ gdb_putpacketz("l");
+ } else
+ gdb_putpacketz("E01");
+}
static void
handle_q_packet(char *packet, int len)
@@ -314,12 +335,10 @@ handle_q_packet(char *packet, int len)
} else if (!strncmp (packet, "qSupported", 10)) {
/* Query supported protocol features */
- gdb_putpacket_f("PacketSize=%X;qXfer:memory-map:read+", BUF_SIZE);
+ gdb_putpacket_f("PacketSize=%X;qXfer:memory-map:read+:qXfer:features:read+", BUF_SIZE);
} else if (strncmp (packet, "qXfer:memory-map:read::", 23) == 0) {
/* Read target XML memory map */
- unsigned long addr, len;
- sscanf(packet+23, "%08lX,%08lX", &addr, &len);
if((!cur_target) && last_target) {
/* Attach to last target if detached. */
cur_target = last_target;
@@ -329,17 +348,20 @@ handle_q_packet(char *packet, int len)
gdb_putpacketz("E01");
return;
}
- if (addr < strlen (cur_target->xml_mem_map)) {
- uint8_t reply[len+2];
- reply[0] = 'm';
- strncpy (reply + 1, &cur_target->xml_mem_map[addr], len);
- if(len > strlen(&cur_target->xml_mem_map[addr]))
- len = strlen(&cur_target->xml_mem_map[addr]);
- gdb_putpacket(reply, len + 1);
- } else if (addr == strlen (cur_target->xml_mem_map)) {
- gdb_putpacketz("l");
- } else
+ handle_q_string_reply(cur_target->xml_mem_map, packet + 23);
+
+ } else if (strncmp (packet, "qXfer:features:read:target.xml:", 31) == 0) {
+ /* Read target description */
+ if((!cur_target) && last_target) {
+ /* Attach to last target if detached. */
+ cur_target = last_target;
+ target_attach(cur_target);
+ }
+ if((!cur_target) || (!cur_target->tdesc)) {
gdb_putpacketz("E01");
+ return;
+ }
+ handle_q_string_reply(cur_target->tdesc, packet + 31);
} else gdb_putpacket("", 0);
}