gdb_server.c 57.6 KB
Newer Older
1001
1002

#ifdef _DEBUG_GDB_IO_
1003
	LOG_DEBUG("-");
1004
1005
1006
1007
1008
1009
1010
1011
#endif

	/* skip command character */
	packet++;
	packet_size--;

	if (packet_size % 2)
	{
1012
		LOG_WARNING("GDB set_registers packet with uneven characters received, dropping connection");
1013
1014
1015
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1016
	if ((retval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
1017
	{
1018
		return gdb_error(connection, retval);
1019
1020
1021
1022
1023
	}

	packet_p = packet;
	for (i = 0; i < reg_list_size; i++)
	{
zwelch's avatar
zwelch committed
1024
		uint8_t *bin_buf;
1025
		int chars = (CEIL(reg_list[i]->size, 8) * 2);
1026

1027
1028
1029
1030
		if (packet_p + chars > packet + packet_size)
		{
			LOG_ERROR("BUG: register packet is too small for registers");
		}
1031

1032
		reg_arch_type_t *arch_type;
1033
		bin_buf = malloc(CEIL(reg_list[i]->size, 8));
1034
		gdb_target_to_reg(target, packet_p, chars, bin_buf);
1035

ntfreak's avatar
ntfreak committed
1036
		/* get register arch_type, and call set method */
1037
		arch_type = register_get_arch_type(reg_list[i]->arch_type);
1038

1039
1040
		arch_type->set(reg_list[i], bin_buf);

ntfreak's avatar
ntfreak committed
1041
		/* advance packet pointer */
1042
1043
		packet_p += chars;

1044
1045
1046
1047

		free(bin_buf);
	}

ntfreak's avatar
ntfreak committed
1048
	/* free reg_t *reg_list[] array allocated by get_gdb_reg_list */
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
	free(reg_list);

	gdb_put_packet(connection, "OK", 2);

	return ERROR_OK;
}

int gdb_get_register_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	char *reg_packet;
	int reg_num = strtoul(packet + 1, NULL, 16);
	reg_t **reg_list;
	int reg_list_size;
	int retval;

#ifdef _DEBUG_GDB_IO_
1065
	LOG_DEBUG("-");
1066
1067
#endif

zwelch's avatar
zwelch committed
1068
	if ((retval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
1069
	{
1070
		return gdb_error(connection, retval);
1071
1072
1073
1074
	}

	if (reg_list_size <= reg_num)
	{
1075
		LOG_ERROR("gdb requested a non-existing register");
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
		exit(-1);
	}

	reg_packet = malloc(CEIL(reg_list[reg_num]->size, 8) * 2);

	gdb_str_to_target(target, reg_packet, reg_list[reg_num]);

	gdb_put_packet(connection, reg_packet, CEIL(reg_list[reg_num]->size, 8) * 2);

	free(reg_list);
	free(reg_packet);

	return ERROR_OK;
}

int gdb_set_register_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	char *separator;
zwelch's avatar
zwelch committed
1094
	uint8_t *bin_buf;
1095
1096
1097
1098
1099
1100
	int reg_num = strtoul(packet + 1, &separator, 16);
	reg_t **reg_list;
	int reg_list_size;
	int retval;
	reg_arch_type_t *arch_type;

1101
	LOG_DEBUG("-");
1102

zwelch's avatar
zwelch committed
1103
	if ((retval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
1104
	{
1105
		return gdb_error(connection, retval);
1106
1107
1108
1109
	}

	if (reg_list_size < reg_num)
	{
1110
		LOG_ERROR("gdb requested a non-existing register");
1111
		return ERROR_SERVER_REMOTE_CLOSED;
1112
1113
1114
1115
	}

	if (*separator != '=')
	{
1116
		LOG_ERROR("GDB 'set register packet', but no '=' following the register number");
1117
1118
1119
1120
1121
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	/* convert from GDB-string (target-endian) to hex-string (big-endian) */
	bin_buf = malloc(CEIL(reg_list[reg_num]->size, 8));
1122
1123
1124
	int chars = (CEIL(reg_list[reg_num]->size, 8) * 2);

	/* fix!!! add some sanity checks on packet size here */
1125

1126
1127
1128
	gdb_target_to_reg(target, separator + 1, chars, bin_buf);

		/* get register arch_type, and call set method */
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
	arch_type = register_get_arch_type(reg_list[reg_num]->arch_type);
	arch_type->set(reg_list[reg_num], bin_buf);

	gdb_put_packet(connection, "OK", 2);

	free(bin_buf);
	free(reg_list);

	return ERROR_OK;
}

1140
int gdb_error(connection_t *connection, int retval)
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
{
	switch (retval)
	{
		case ERROR_TARGET_DATA_ABORT:
			gdb_send_error(connection, EIO);
			break;
		case ERROR_TARGET_TRANSLATION_FAULT:
			gdb_send_error(connection, EFAULT);
			break;
		case ERROR_TARGET_UNALIGNED_ACCESS:
			gdb_send_error(connection, EFAULT);
			break;
1153
1154
1155
		case ERROR_TARGET_NOT_HALTED:
			gdb_send_error(connection, EFAULT);
			break;
1156
1157
		default:
			/* This could be that the target reset itself. */
1158
			LOG_ERROR("unexpected error %i", retval);
1159
1160
			gdb_send_error(connection, EFAULT);
			break;
1161
1162
1163
1164
1165
1166
1167
	}

	return ERROR_OK;
}

/* We don't have to worry about the default 2 second timeout for GDB packets,
 * because GDB breaks up large memory reads into smaller reads.
ntfreak's avatar
ntfreak committed
1168
 *
1169
1170
1171
1172
1173
 * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192?????
 */
int gdb_read_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	char *separator;
1174
1175
	uint32_t addr = 0;
	uint32_t len = 0;
1176

zwelch's avatar
zwelch committed
1177
	uint8_t *buffer;
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
	char *hex_buffer;

	int retval = ERROR_OK;

	/* skip command character */
	packet++;

	addr = strtoul(packet, &separator, 16);

	if (*separator != ',')
	{
1189
		LOG_ERROR("incomplete read memory packet received, dropping connection");
1190
1191
1192
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1193
	len = strtoul(separator + 1, NULL, 16);
1194
1195
1196

	buffer = malloc(len);

duane's avatar
duane committed
1197
	LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
1198
1199
1200

	retval = target_read_buffer(target, addr, len, buffer);

zwelch's avatar
zwelch committed
1201
	if ((retval != ERROR_OK)&&!gdb_report_data_abort)
1202
1203
1204
	{
		/* 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.
ntfreak's avatar
ntfreak committed
1205
		 *
1206
1207
1208
		 * 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
ntfreak's avatar
ntfreak committed
1209
		 *
zwelch's avatar
zwelch committed
1210
		 * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd = view%20audit-trail&database = gdb&pr = 2395
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
		 *
		 * 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;
	}

	if (retval == ERROR_OK)
	{
		hex_buffer = malloc(len * 2 + 1);

1223
		uint32_t i;
1224
1225
		for (i = 0; i < len; i++)
		{
zwelch's avatar
zwelch committed
1226
			uint8_t t = buffer[i];
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
			hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf];
			hex_buffer[2 * i + 1] = DIGITS[t & 0xf];
		}

		gdb_put_packet(connection, hex_buffer, len * 2);

		free(hex_buffer);
	}
	else
	{
1237
		retval = gdb_error(connection, retval);
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
	}

	free(buffer);

	return retval;
}

int gdb_write_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	char *separator;
1248
1249
	uint32_t addr = 0;
	uint32_t len = 0;
1250

zwelch's avatar
zwelch committed
1251
	uint8_t *buffer;
1252

1253
	uint32_t i;
1254
1255
1256
1257
1258
1259
1260
1261
1262
	int retval;

	/* skip command character */
	packet++;

	addr = strtoul(packet, &separator, 16);

	if (*separator != ',')
	{
1263
		LOG_ERROR("incomplete write memory packet received, dropping connection");
1264
1265
1266
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1267
	len = strtoul(separator + 1, &separator, 16);
1268
1269
1270

	if (*(separator++) != ':')
	{
1271
		LOG_ERROR("incomplete write memory packet received, dropping connection");
1272
1273
1274
1275
1276
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	buffer = malloc(len);

duane's avatar
duane committed
1277
	LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
1278

zwelch's avatar
zwelch committed
1279
	for (i = 0; i < len; i++)
1280
	{
1281
		uint32_t tmp;
duane's avatar
duane committed
1282
		sscanf(separator + 2*i, "%2" SCNx32 , &tmp);
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
		buffer[i] = tmp;
	}

	retval = target_write_buffer(target, addr, len, buffer);

	if (retval == ERROR_OK)
	{
		gdb_put_packet(connection, "OK", 2);
	}
	else
	{
1294
		retval = gdb_error(connection, retval);
1295
1296
1297
1298
	}

	free(buffer);

1299
	return retval;
1300
1301
1302
1303
1304
}

int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	char *separator;
1305
1306
	uint32_t addr = 0;
	uint32_t len = 0;
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316

	int retval;

	/* skip command character */
	packet++;

	addr = strtoul(packet, &separator, 16);

	if (*separator != ',')
	{
1317
		LOG_ERROR("incomplete write memory binary packet received, dropping connection");
1318
1319
1320
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1321
	len = strtoul(separator + 1, &separator, 16);
1322
1323
1324

	if (*(separator++) != ':')
	{
1325
		LOG_ERROR("incomplete write memory binary packet received, dropping connection");
1326
1327
1328
1329
1330
1331
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	retval = ERROR_OK;
	if (len)
	{
duane's avatar
duane committed
1332
		LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
1333

zwelch's avatar
zwelch committed
1334
		retval = target_write_buffer(target, addr, len, (uint8_t*)separator);
1335
1336
1337
1338
1339
1340
1341
1342
	}

	if (retval == ERROR_OK)
	{
		gdb_put_packet(connection, "OK", 2);
	}
	else
	{
1343
		if ((retval = gdb_error(connection, retval)) != ERROR_OK)
ntfreak's avatar
ntfreak committed
1344
			return retval;
1345
1346
1347
1348
1349
	}

	return ERROR_OK;
}

1350
int gdb_step_continue_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
1351
1352
{
	int current = 0;
1353
	uint32_t address = 0x0;
zwelch's avatar
zwelch committed
1354
	int retval = ERROR_OK;
1355

1356
	LOG_DEBUG("-");
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369

	if (packet_size > 1)
	{
		packet[packet_size] = 0;
		address = strtoul(packet + 1, NULL, 16);
	}
	else
	{
		current = 1;
	}

	if (packet[0] == 'c')
	{
1370
		LOG_DEBUG("continue");
1371
		target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
zwelch's avatar
zwelch committed
1372
		retval = target_resume(target, current, address, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */
1373
1374
1375
	}
	else if (packet[0] == 's')
	{
1376
		LOG_DEBUG("step");
zwelch's avatar
zwelch committed
1377
1378
		/* step at current or address, don't handle breakpoints */
		retval = target_step(target, current, address, 0);
1379
	}
1380
	return retval;
1381
1382
1383
1384
1385
1386
1387
}

int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	int type;
	enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
	enum watchpoint_rw wp_type;
1388
1389
	uint32_t address;
	uint32_t size;
1390
1391
1392
	char *separator;
	int retval;

1393
	LOG_DEBUG("-");
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406

	type = strtoul(packet + 1, &separator, 16);

	if (type == 0)	/* memory breakpoint */
		bp_type = BKPT_SOFT;
	else if (type == 1) /* hardware breakpoint */
		bp_type = BKPT_HARD;
	else if (type == 2) /* write watchpoint */
		wp_type = WPT_WRITE;
	else if (type == 3) /* read watchpoint */
		wp_type = WPT_READ;
	else if (type == 4) /* access watchpoint */
		wp_type = WPT_ACCESS;
1407

zwelch's avatar
zwelch committed
1408
	if (gdb_breakpoint_override && ((bp_type == BKPT_SOFT)||(bp_type == BKPT_HARD)))
1409
	{
zwelch's avatar
zwelch committed
1410
		bp_type = gdb_breakpoint_override_type;
1411
	}
1412
1413
1414

	if (*separator != ',')
	{
1415
		LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1416
1417
1418
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1419
	address = strtoul(separator + 1, &separator, 16);
1420
1421
1422

	if (*separator != ',')
	{
1423
		LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1424
1425
1426
		return ERROR_SERVER_REMOTE_CLOSED;
	}

zwelch's avatar
zwelch committed
1427
	size = strtoul(separator + 1, &separator, 16);
1428
1429
1430
1431
1432
1433
1434
1435
1436

	switch (type)
	{
		case 0:
		case 1:
			if (packet[0] == 'Z')
			{
				if ((retval = breakpoint_add(target, address, size, bp_type)) != ERROR_OK)
				{
1437
					if ((retval = gdb_error(connection, retval)) != ERROR_OK)
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
						return retval;
				}
				else
				{
					gdb_put_packet(connection, "OK", 2);
				}
			}
			else
			{
				breakpoint_remove(target, address);
				gdb_put_packet(connection, "OK", 2);
			}
			break;
		case 2:
		case 3:
		case 4:
		{
			if (packet[0] == 'Z')
			{
				if ((retval = watchpoint_add(target, address, size, type-2, 0, 0xffffffffu)) != ERROR_OK)
				{
1459
					if ((retval = gdb_error(connection, retval)) != ERROR_OK)
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
						return retval;
				}
				else
				{
					gdb_put_packet(connection, "OK", 2);
				}
			}
			else
			{
				watchpoint_remove(target, address);
				gdb_put_packet(connection, "OK", 2);
			}
			break;
		}
		default:
			break;
	}

	return ERROR_OK;
}

/* print out a string and allocate more space as needed, mainly used for XML at this point */
void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, ...)
{
	if (*retval != ERROR_OK)
	{
		return;
	}
	int first = 1;
ntfreak's avatar
ntfreak committed
1489

1490
1491
1492
1493
1494
1495
	for (;;)
	{
		if ((*xml == NULL) || (!first))
		{
			/* start by 0 to exercise all the code paths.
			 * Need minimum 2 bytes to fit 1 char and 0 terminator. */
ntfreak's avatar
ntfreak committed
1496

1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
			*size = *size * 2 + 2;
			char *t = *xml;
			*xml = realloc(*xml, *size);
			if (*xml == NULL)
			{
				if (t)
					free(t);
				*retval = ERROR_SERVER_REMOTE_CLOSED;
				return;
			}
		}
ntfreak's avatar
ntfreak committed
1508

1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
		va_list ap;
		int ret;
		va_start(ap, fmt);
		ret = vsnprintf(*xml + *pos, *size - *pos, fmt, ap);
		va_end(ap);
		if ((ret > 0) && ((ret + 1) < *size - *pos))
		{
			*pos += ret;
			return;
		}
		/* there was just enough or not enough space, allocate more. */
		first = 0;
1521
1522
1523
1524
1525
1526
	}
}

static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len)
{
	char *separator;
ntfreak's avatar
ntfreak committed
1527

1528
1529
1530
1531
1532
1533
1534
	/* Extract and NUL-terminate the annex. */
	*annex = buf;
	while (*buf && *buf != ':')
		buf++;
	if (*buf == '\0')
		return -1;
	*buf++ = 0;
ntfreak's avatar
ntfreak committed
1535

1536
1537
	/* After the read marker and annex, qXfer looks like a
	 * traditional 'm' packet. */
ntfreak's avatar
ntfreak committed
1538

1539
1540
1541
1542
1543
	*ofs = strtoul(buf, &separator, 16);

	if (*separator != ',')
		return -1;

zwelch's avatar
zwelch committed
1544
	*len = strtoul(separator + 1, NULL, 16);
ntfreak's avatar
ntfreak committed
1545

1546
1547
1548
1549
1550
	return 0;
}

int gdb_calc_blocksize(flash_bank_t *bank)
{
1551
1552
	uint32_t i;
	uint32_t block_size = 0xffffffff;
ntfreak's avatar
ntfreak committed
1553

1554
	/* loop through all sectors and return smallest sector size */
ntfreak's avatar
ntfreak committed
1555

1556
	for (i = 0; i < (uint32_t)bank->num_sectors; i++)
1557
1558
1559
1560
	{
		if (bank->sectors[i].size < block_size)
			block_size = bank->sectors[i].size;
	}
ntfreak's avatar
ntfreak committed
1561

1562
1563
1564
	return block_size;
}

1565
1566
1567
1568
1569
static int compare_bank (const void * a, const void * b)
{
	flash_bank_t *b1, *b2;
	b1=*((flash_bank_t **)a);
	b2=*((flash_bank_t **)b);
1570

zwelch's avatar
zwelch committed
1571
	if (b1->base == b2->base)
1572
1573
	{
		return 0;
zwelch's avatar
zwelch committed
1574
	} else if (b1->base > b2->base)
1575
1576
1577
1578
1579
1580
1581
1582
	{
		return 1;
	} else
	{
		return -1;
	}
}

1583
1584
1585
int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	command_context_t *cmd_ctx = connection->cmd_ctx;
1586
	gdb_connection_t *gdb_connection = connection->priv;
1587

1588
1589
1590
1591
1592
1593
1594
	if (strstr(packet, "qRcmd,"))
	{
		if (packet_size > 6)
		{
			char *cmd;
			int i;
			cmd = malloc((packet_size - 6)/2 + 1);
zwelch's avatar
zwelch committed
1595
			for (i = 0; i < (packet_size - 6)/2; i++)
1596
			{
1597
				uint32_t tmp;
duane's avatar
duane committed
1598
				sscanf(packet + 6 + 2*i, "%2" SCNx32 , &tmp);
1599
1600
1601
				cmd[i] = tmp;
			}
			cmd[(packet_size - 6)/2] = 0x0;
ntfreak's avatar
ntfreak committed
1602

1603
1604
			/* We want to print all debug output to GDB connection */
			log_add_callback(gdb_log_callback, connection);
1605
			target_call_timer_callbacks_now();
1606
			command_run_line(cmd_ctx, cmd);
1607
			target_call_timer_callbacks_now();
oharboe's avatar
oharboe committed
1608
			log_remove_callback(gdb_log_callback, connection);
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
			free(cmd);
		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}
	else if (strstr(packet, "qCRC:"))
	{
		if (packet_size > 5)
		{
			int retval;
			char gdb_reply[10];
			char *separator;
1621
1622
1623
			uint32_t checksum;
			uint32_t addr = 0;
			uint32_t len = 0;
ntfreak's avatar
ntfreak committed
1624

1625
1626
			/* skip command character */
			packet += 5;
ntfreak's avatar
ntfreak committed
1627

1628
			addr = strtoul(packet, &separator, 16);
ntfreak's avatar
ntfreak committed
1629

1630
1631
			if (*separator != ',')
			{
1632
				LOG_ERROR("incomplete read memory packet received, dropping connection");
1633
1634
				return ERROR_SERVER_REMOTE_CLOSED;
			}
ntfreak's avatar
ntfreak committed
1635

1636
			len = strtoul(separator + 1, NULL, 16);
ntfreak's avatar
ntfreak committed
1637

1638
			retval = target_checksum_memory(target, addr, len, &checksum);
ntfreak's avatar
ntfreak committed
1639

1640
1641
			if (retval == ERROR_OK)
			{
duane's avatar
duane committed
1642
				snprintf(gdb_reply, 10, "C%8.8" PRIx32 "", checksum);
1643
1644
1645
1646
				gdb_put_packet(connection, gdb_reply, 9);
			}
			else
			{
1647
				if ((retval = gdb_error(connection, retval)) != ERROR_OK)
ntfreak's avatar
ntfreak committed
1648
					return retval;
1649
			}
ntfreak's avatar
ntfreak committed
1650

1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
			return ERROR_OK;
		}
	}
	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;

ntfreak's avatar
ntfreak committed
1663
		xml_printf(&retval, &buffer, &pos, &size,
1664
				"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-;QStartNoAckMode+",
zwelch's avatar
zwelch committed
1665
				(GDB_BUFFER_SIZE - 1), ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-');
ntfreak's avatar
ntfreak committed
1666

1667
1668
1669
1670
1671
		if (retval != ERROR_OK)
		{
			gdb_send_error(connection, 01);
			return ERROR_OK;
		}
ntfreak's avatar
ntfreak committed
1672

1673
1674
		gdb_put_packet(connection, buffer, strlen(buffer));
		free(buffer);
ntfreak's avatar
ntfreak committed
1675

1676
1677
		return ERROR_OK;
	}
zwelch's avatar
zwelch committed
1678
	else if (strstr(packet, "qXfer:memory-map:read::") && (flash_get_bank_count() > 0))
1679
1680
	{
		/* We get away with only specifying flash here. Regions that are not
ntfreak's avatar
ntfreak committed
1681
		 * specified are treated as if we provided no memory map(if not we
1682
1683
1684
		 * 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. */
ntfreak's avatar
ntfreak committed
1685

1686
1687
1688
1689
1690
		flash_bank_t *p;
		char *xml = NULL;
		int size = 0;
		int pos = 0;
		int retval = ERROR_OK;
ntfreak's avatar
ntfreak committed
1691

1692
1693
1694
1695
		int offset;
		int length;
		char *separator;
		int blocksize;
ntfreak's avatar
ntfreak committed
1696

1697
1698
		/* skip command character */
		packet += 23;
ntfreak's avatar
ntfreak committed
1699

1700
1701
		offset = strtoul(packet, &separator, 16);
		length = strtoul(separator + 1, &separator, 16);
ntfreak's avatar
ntfreak committed
1702

1703
		xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n");
1704
1705

		/*
1706
1707
1708
1709
		sort banks in ascending order, we need to make non-flash memory be ram(or rather
		read/write) by default for GDB.
		GDB does not have a concept of non-cacheable read/write memory.
		 */
zwelch's avatar
zwelch committed
1710
		flash_bank_t **banks = malloc(sizeof(flash_bank_t *)*flash_get_bank_count());
oharboe's avatar
oharboe committed
1711
		int i;
1712

zwelch's avatar
zwelch committed
1713
		for (i = 0; i < flash_get_bank_count(); i++)
1714
1715
1716
		{
			p = get_flash_bank_by_num(i);
			if (p == NULL)
1717
1718
1719
1720
1721
1722
1723
1724
			{
				free(banks);
				retval = ERROR_FAIL;
				gdb_send_error(connection, retval);
				return retval;
			}
			banks[i]=p;
		}
1725

1726
		qsort(banks, flash_get_bank_count(), sizeof(flash_bank_t *), compare_bank);
1727

zwelch's avatar
zwelch committed
1728
		uint32_t ram_start = 0;
zwelch's avatar
zwelch committed
1729
		for (i = 0; i < flash_get_bank_count(); i++)
1730
1731
		{
			p = banks[i];
1732

zwelch's avatar
zwelch committed
1733
			if (ram_start < p->base)
1734
1735
1736
1737
			{
				xml_printf(&retval, &xml, &pos, &size, "<memory type=\"ram\" start=\"0x%x\" length=\"0x%x\"/>\n",
					ram_start, p->base-ram_start);
			}
1738

1739
1740
1741
			/* if device has uneven sector sizes, eg. str7, lpc
			 * we pass the smallest sector size to gdb memory map */
			blocksize = gdb_calc_blocksize(p);
1742

1743
1744
1745
1746
			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);
zwelch's avatar
zwelch committed
1747
			ram_start = p->base + p->size;
1748
		}
zwelch's avatar
zwelch committed
1749
		if (ram_start != 0)
1750
1751
1752
1753
1754
1755
1756
		{
			xml_printf(&retval, &xml, &pos, &size, "<memory type=\"ram\" start=\"0x%x\" length=\"0x%x\"/>\n",
				ram_start, 0-ram_start);
		} else
		{
			/* a flash chip could be at the very end of the 32 bit address space, in which case
			ram_start will be precisely 0 */
1757
		}
1758

1759
1760
		free(banks);
		banks = NULL;
ntfreak's avatar
ntfreak committed
1761

1762
1763
1764
1765
1766
1767
1768
		xml_printf(&retval, &xml, &pos, &size, "</memory-map>\n");

		if (retval != ERROR_OK)
		{
			gdb_send_error(connection, retval);
			return retval;
		}
ntfreak's avatar
ntfreak committed
1769

1770
1771
1772
1773
1774
1775
1776
1777
1778
		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);
ntfreak's avatar
ntfreak committed
1779

1780
1781
1782
1783
1784
		free(t);
		free(xml);
		return ERROR_OK;
	}
	else if (strstr(packet, "qXfer:features:read:"))
ntfreak's avatar
ntfreak committed
1785
	{
1786
1787
1788
1789
		char *xml = NULL;
		int size = 0;
		int pos = 0;
		int retval = ERROR_OK;
ntfreak's avatar
ntfreak committed
1790

1791
1792
1793
		int offset;
		unsigned int length;
		char *annex;
ntfreak's avatar
ntfreak committed
1794

1795
1796
		/* skip command character */
		packet += 20;
ntfreak's avatar
ntfreak committed
1797

1798
1799
1800
1801
1802
		if (decode_xfer_read(packet, &annex, &offset, &length) < 0)
		{
			gdb_send_error(connection, 01);
			return ERROR_OK;
		}
ntfreak's avatar
ntfreak committed
1803

1804
1805
1806
1807
1808
		if (strcmp(annex, "target.xml") != 0)
		{
			gdb_send_error(connection, 01);
			return ERROR_OK;
		}
ntfreak's avatar
ntfreak committed
1809

1810
		xml_printf(&retval, &xml, &pos, &size, \
zwelch's avatar
zwelch committed
1811
			"l < target version=\"1.0\">\n < architecture > arm</architecture>\n</target>\n");
ntfreak's avatar
ntfreak committed
1812

1813
1814
1815
1816
1817
		if (retval != ERROR_OK)
		{
			gdb_send_error(connection, retval);
			return retval;
		}
ntfreak's avatar
ntfreak committed
1818

1819
		gdb_put_packet(connection, xml, strlen(xml));
ntfreak's avatar
ntfreak committed
1820

1821
1822
1823
		free(xml);
		return ERROR_OK;
	}
1824
1825
1826
1827
1828
1829
	else if (strstr(packet, "QStartNoAckMode"))
	{
		gdb_connection->noack_mode = 1;
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}
ntfreak's avatar
ntfreak committed
1830

1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
	gdb_put_packet(connection, "", 0);
	return ERROR_OK;
}

int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
	gdb_connection_t *gdb_connection = connection->priv;
	gdb_service_t *gdb_service = connection->service->priv;
	int result;

	/* if flash programming disabled - send a empty reply */
ntfreak's avatar
ntfreak committed
1842

1843
1844
1845
1846
1847
	if (gdb_flash_program == 0)
	{
		gdb_put_packet(connection, "", 0);
		return ERROR_OK;
	}
ntfreak's avatar
ntfreak committed
1848

1849
1850
1851
1852
	if (strstr(packet, "vFlashErase:"))
	{
		unsigned long addr;
		unsigned long length;
ntfreak's avatar
ntfreak committed
1853

1854
1855
1856
		char *parse = packet + 12;
		if (*parse == '\0')
		{
1857
			LOG_ERROR("incomplete vFlashErase packet received, dropping connection");
1858
1859
1860
1861
1862
1863
1864
			return ERROR_SERVER_REMOTE_CLOSED;
		}

		addr = strtoul(parse, &parse, 16);

		if (*(parse++) != ',' || *parse == '\0')
		{
1865
			LOG_ERROR("incomplete vFlashErase packet received, dropping connection");
1866
1867
1868
1869
1870
1871
1872
			return ERROR_SERVER_REMOTE_CLOSED;
		}

		length = strtoul(parse, &parse, 16);

		if (*parse != '\0')
		{
1873
			LOG_ERROR("incomplete vFlashErase packet received, dropping connection");
1874
1875
			return ERROR_SERVER_REMOTE_CLOSED;
		}
ntfreak's avatar
ntfreak committed
1876

1877
1878
1879
		/* assume all sectors need erasing - stops any problems
		 * when flash_write is called multiple times */
		flash_set_dirty();
ntfreak's avatar
ntfreak committed
1880

1881
		/* perform any target specific operations before the erase */
1882
		target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_START);
1883
		result = flash_erase_address_range(gdb_service->target, addr, length);
1884
		target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_END);
ntfreak's avatar
ntfreak committed
1885

1886
		/* perform erase */
1887
		if (result != ERROR_OK)
1888
1889
1890
1891
1892
		{
			/* GDB doesn't evaluate the actual error number returned,
			 * treat a failed erase as an I/O error
			 */
			gdb_send_error(connection, EIO);
1893
			LOG_ERROR("flash_erase returned %i", result);
1894
1895
1896
		}
		else
			gdb_put_packet(connection, "OK", 2);
ntfreak's avatar
ntfreak committed
1897

1898
1899
1900
1901
1902
		return ERROR_OK;
	}

	if (strstr(packet, "vFlashWrite:"))
	{
1903
		int retval;
1904
1905
1906
1907
1908
1909
		unsigned long addr;
		unsigned long length;
		char *parse = packet + 12;

		if (*parse == '\0')
		{
1910
			LOG_ERROR("incomplete vFlashErase packet received, dropping connection");
1911
1912
1913
1914
1915
			return ERROR_SERVER_REMOTE_CLOSED;
		}
		addr = strtoul(parse, &parse, 16);
		if (*(parse++) != ':')
		{
1916
			LOG_ERROR("incomplete vFlashErase packet received, dropping connection");
1917
1918
1919
			return ERROR_SERVER_REMOTE_CLOSED;
		}
		length = packet_size - (parse - packet);
ntfreak's avatar
ntfreak committed
1920

1921
1922
1923
1924
1925
1926
1927
1928
		/* create a new image if there isn't already one */
		if (gdb_connection->vflash_image == NULL)
		{
			gdb_connection->vflash_image = malloc(sizeof(image_t));
			image_open(gdb_connection->vflash_image, "", "build");
		}

		/* create new section with content from packet buffer */
zwelch's avatar
zwelch committed
1929
		if ((retval = image_add_section(gdb_connection->vflash_image, addr, length, 0x0, (uint8_t*)parse)) != ERROR_OK)
1930
1931
1932
		{
			return retval;
		}
1933
1934
1935
1936
1937
1938
1939
1940

		gdb_put_packet(connection, "OK", 2);

		return ERROR_OK;
	}

	if (!strcmp(packet, "vFlashDone"))
	{
1941
		uint32_t written;
1942
1943
1944

		/* process the flashing buffer. No need to erase as GDB
		 * always issues a vFlashErase first. */
1945
1946
1947
		target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_WRITE_START);
		result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, 0);
		target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_WRITE_END);
1948
		if (result != ERROR_OK)
1949
1950
1951
1952
1953
1954
1955
1956
		{
			if (result == ERROR_FLASH_DST_OUT_OF_BANK)
				gdb_put_packet(connection, "E.memtype", 9);
			else
				gdb_send_error(connection, EIO);
			}
		else
		{
duane's avatar
duane committed
1957
			LOG_DEBUG("wrote %u bytes from vFlash image to flash", (unsigned)written);
1958
1959
			gdb_put_packet(connection, "OK", 2);
		}
ntfreak's avatar
ntfreak committed
1960

1961
1962
1963
		image_close(gdb_connection->vflash_image);
		free(gdb_connection->vflash_image);
		gdb_connection->vflash_image = NULL;
ntfreak's avatar
ntfreak committed
1964

1965
1966
1967
1968
1969
1970
1971
1972
1973
		return ERROR_OK;
	}

	gdb_put_packet(connection, "", 0);
	return ERROR_OK;
}

int gdb_detach(connection_t *connection, target_t *target)
{
1974

1975
	switch (detach_mode)
1976
1977
	{
		case GDB_DETACH_RESUME:
1978
			target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
1979
			target_resume(target, 1, 0, 1, 0);
1980
			break;
ntfreak's avatar
ntfreak committed
1981

1982
		case GDB_DETACH_RESET:
oharboe's avatar
   
oharboe committed
1983
1984
			/* FIX?? make this configurable?? */
			target_process_reset(connection->cmd_ctx, RESET_HALT);
1985
			break;
ntfreak's avatar
ntfreak committed
1986

1987
		case GDB_DETACH_HALT:
1988
			target_halt(target);
1989
			break;
ntfreak's avatar
ntfreak committed
1990

1991
1992
1993
		case GDB_DETACH_NOTHING:
			break;
	}
ntfreak's avatar
ntfreak committed
1994

1995
1996
1997
1998
	gdb_put_packet(connection, "OK", 2);
	return ERROR_OK;
}

ntfreak's avatar
ntfreak committed
1999
static void gdb_log_callback(void *priv, const char *file, int line,
2000
		const char *function, const char *string)
For faster browsing, not all history is shown. View entire blame