+ else if (strstr(packet, "qSupported"))
+ {
+ /* we currently support packet size and qXfer:memory-map:read (if enabled)
+ * disable qXfer:features:read for the moment */
+ int retval = ERROR_OK;
+ char *buffer = NULL;
+ int pos = 0;
+ int size = 0;
+
+ xml_printf(&retval, &buffer, &pos, &size,
+ "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-",
+ (GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-');
+
+ if (retval != ERROR_OK)
+ {
+ gdb_send_error(connection, 01);
+ return ERROR_OK;
+ }
+
+ gdb_put_packet(connection, buffer, strlen(buffer));
+ free(buffer);
+
+ return ERROR_OK;
+ }
+ else if (strstr(packet, "qXfer:memory-map:read::"))
+ {
+ /* We get away with only specifying flash here. Regions that are not
+ * specified are treated as if we provided no memory map(if not we
+ * could detect the holes and mark them as RAM).
+ * Normally we only execute this code once, but no big deal if we
+ * have to regenerate it a couple of times. */
+
+ flash_bank_t *p;
+ char *xml = NULL;
+ int size = 0;
+ int pos = 0;
+ int retval = ERROR_OK;
+
+ int offset;
+ int length;
+ char *separator;
+ int blocksize;
+
+ /* skip command character */
+ packet += 23;
+
+ offset = strtoul(packet, &separator, 16);
+ length = strtoul(separator + 1, &separator, 16);
+
+ xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n");
+
+ int i = 0;
+ for (;;)
+ {
+ p = get_flash_bank_by_num(i);
+ if (p == NULL)
+ break;
+
+ /* if device has uneven sector sizes, eg. str7, lpc
+ * we pass the smallest sector size to gdb memory map */
+ blocksize = gdb_calc_blocksize(p);
+
+ xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
+ "<property name=\"blocksize\">0x%x</property>\n" \
+ "</memory>\n", \
+ p->base, p->size, blocksize);
+ i++;
+ }
+
+ xml_printf(&retval, &xml, &pos, &size, "</memory-map>\n");
+
+ if (retval != ERROR_OK)
+ {
+ gdb_send_error(connection, retval);
+ return retval;
+ }
+
+ if (offset + length > pos)
+ {
+ length = pos - offset;
+ }
+
+ char *t = malloc(length + 1);
+ t[0] = 'l';
+ memcpy(t + 1, xml + offset, length);
+ gdb_put_packet(connection, t, length + 1);
+
+ free(t);
+ free(xml);
+ return ERROR_OK;
+ }
+ else if (strstr(packet, "qXfer:features:read:"))
+ {
+ char *xml = NULL;
+ int size = 0;
+ int pos = 0;
+ int retval = ERROR_OK;
+
+ int offset;
+ unsigned int length;
+ char *annex;
+
+ /* skip command character */
+ packet += 20;
+
+ if (decode_xfer_read(packet, &annex, &offset, &length) < 0)
+ {
+ gdb_send_error(connection, 01);
+ return ERROR_OK;
+ }
+
+ if (strcmp(annex, "target.xml") != 0)
+ {
+ gdb_send_error(connection, 01);
+ return ERROR_OK;
+ }
+
+ xml_printf(&retval, &xml, &pos, &size, \
+ "l<target version=\"1.0\">\n<architecture>arm</architecture>\n</target>\n");
+
+ if (retval != ERROR_OK)
+ {
+ gdb_send_error(connection, retval);
+ return retval;
+ }
+
+ gdb_put_packet(connection, xml, strlen(xml) + 1);
+
+ free(xml);
+ return ERROR_OK;
+ }