gdb_server.c 57.6 KB
Newer Older
2001
2002
2003
{
	connection_t *connection = priv;
	gdb_connection_t *gdb_con = connection->priv;
ntfreak's avatar
ntfreak committed
2004

2005
2006
2007
2008
2009
2010
	if (gdb_con->busy)
	{
		/* do not reply this using the O packet */
		return;
	}

2011
	gdb_output_con(connection, string);
2012
2013
}

2014
2015
2016
/* Do not allocate this on the stack */
char gdb_packet_buffer[GDB_BUFFER_SIZE];

2017
2018
2019
2020
2021
2022
2023
2024
static void gdb_sig_halted(connection_t *connection)
{
	char sig_reply[4];
	snprintf(sig_reply, 4, "T%2.2x", 2);
	gdb_put_packet(connection, sig_reply, 3);

}

2025
2026
2027
2028
int gdb_input_inner(connection_t *connection)
{
	gdb_service_t *gdb_service = connection->service->priv;
	target_t *target = gdb_service->target;
zwelch's avatar
zwelch committed
2029
	char *packet = gdb_packet_buffer;
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
	int packet_size;
	int retval;
	gdb_connection_t *gdb_con = connection->priv;
	static int extended_protocol = 0;

	/* drain input buffer */
	do
	{
		packet_size = GDB_BUFFER_SIZE-1;
		if ((retval = gdb_get_packet(connection, packet, &packet_size)) != ERROR_OK)
		{
			return retval;
		}

		/* terminate with zero */
		packet[packet_size] = 0;

zwelch's avatar
zwelch committed
2047
2048
		if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
			if (packet[0] == 'X') {
oharboe's avatar
oharboe committed
2049
				// binary packets spew junk into the debug log stream
2050
2051
				char buf[ 50 ];
				int x;
zwelch's avatar
zwelch committed
2052
				for (x = 0 ; (x < 49) && (packet[x] != ':') ; x++) {
2053
2054
2055
					buf[x] = packet[x];
				}
				buf[x] = 0;
2056
				LOG_DEBUG("received packet: '%s:<binary-data>'", buf);
2057
			} else {
2058
				LOG_DEBUG("received packet: '%s'", packet);
2059
2060
			}
		}
2061
2062
2063
2064
2065
2066
2067

		if (packet_size > 0)
		{
			retval = ERROR_OK;
			switch (packet[0])
			{
				case 'H':
ntfreak's avatar
ntfreak committed
2068
					/* Hct... -- set thread
2069
2070
2071
2072
					 * we don't have threads, send empty reply */
					gdb_put_packet(connection, NULL, 0);
					break;
				case 'q':
2073
				case 'Q':
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
					retval = gdb_query_packet(connection, target, packet, packet_size);
					break;
				case 'g':
					retval = gdb_get_registers_packet(connection, target, packet, packet_size);
					break;
				case 'G':
					retval = gdb_set_registers_packet(connection, target, packet, packet_size);
					break;
				case 'p':
					retval = gdb_get_register_packet(connection, target, packet, packet_size);
					break;
				case 'P':
					retval = gdb_set_register_packet(connection, target, packet, packet_size);
					break;
				case 'm':
					retval = gdb_read_memory_packet(connection, target, packet, packet_size);
					break;
				case 'M':
					retval = gdb_write_memory_packet(connection, target, packet, packet_size);
					break;
				case 'z':
				case 'Z':
					retval = gdb_breakpoint_watchpoint_packet(connection, target, packet, packet_size);
					break;
				case '?':
					gdb_last_signal_packet(connection, target, packet, packet_size);
					break;
				case 'c':
				case 's':
					{
2104
2105
2106
2107
2108
						if (target->state != TARGET_HALTED)
						{
							/* If the target isn't in the halted state, then we can't
							 * step/continue. This might be early setup, etc.
							 */
2109
							gdb_sig_halted(connection);
2110
2111
2112
						} else
						{
							/* We're running/stepping, in which case we can
2113
							 * forward log output until the target is halted
2114
2115
2116
2117
							 */
							gdb_connection_t *gdb_con = connection->priv;
							gdb_con->frontend_state = TARGET_RUNNING;
							log_add_callback(gdb_log_callback, connection);
2118
							target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
zwelch's avatar
zwelch committed
2119
							int retval = gdb_step_continue_packet(connection, target, packet, packet_size);
zwelch's avatar
zwelch committed
2120
							if (retval != ERROR_OK)
2121
2122
							{
								/* we'll never receive a halted condition... issue a false one.. */
2123
								gdb_frontend_halted(target, connection);
2124
							}
2125
						}
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
					}
					break;
				case 'v':
					retval = gdb_v_packet(connection, target, packet, packet_size);
					break;
				case 'D':
					retval = gdb_detach(connection, target);
					extended_protocol = 0;
					break;
				case 'X':
					if ((retval = gdb_write_memory_binary_packet(connection, target, packet, packet_size)) != ERROR_OK)
						return retval;
					break;
				case 'k':
					if (extended_protocol != 0)
						break;
					gdb_put_packet(connection, "OK", 2);
					return ERROR_SERVER_REMOTE_CLOSED;
				case '!':
					/* handle extended remote protocol */
					extended_protocol = 1;
					gdb_put_packet(connection, "OK", 2);
					break;
				case 'R':
					/* handle extended restart packet */
2151
2152
					breakpoint_clear_target(gdb_service->target);
					watchpoint_clear_target(gdb_service->target);
oharboe's avatar
oharboe committed
2153
					command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %d", get_num_by_target(target));
2154
2155
2156
					break;
				default:
					/* ignore unkown packets */
2157
					LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]);
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
					gdb_put_packet(connection, NULL, 0);
					break;
			}

			/* if a packet handler returned an error, exit input loop */
			if (retval != ERROR_OK)
				return retval;
		}

		if (gdb_con->ctrl_c)
		{
			if (target->state == TARGET_RUNNING)
			{
2171
				target_halt(target);
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
				gdb_con->ctrl_c = 0;
			}
		}

	} while (gdb_con->buf_cnt > 0);

	return ERROR_OK;
}

int gdb_input(connection_t *connection)
{
	int retval = gdb_input_inner(connection);
2184
	gdb_connection_t *gdb_con = connection->priv;
2185
2186
	if (retval == ERROR_SERVER_REMOTE_CLOSED)
		return retval;
2187

2188
	/* logging does not propagate the error, yet can set the gdb_con->closed flag */
2189
2190
	if (gdb_con->closed)
		return ERROR_SERVER_REMOTE_CLOSED;
2191

2192
2193
2194
2195
	/* we'll recover from any other errors(e.g. temporary timeouts, etc.) */
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
2196
int gdb_init(void)
2197
2198
{
	gdb_service_t *gdb_service;
2199
	target_t *target = all_targets;
2200
2201
2202

	if (!target)
	{
2203
		LOG_WARNING("no gdb ports allocated as no target has been specified");
2204
2205
2206
		return ERROR_OK;
	}

2207
	if (gdb_port == 0 && server_use_pipes == 0)
2208
	{
zwelch's avatar
zwelch committed
2209
2210
		LOG_INFO("gdb port disabled");
		return ERROR_OK;
2211
2212
	}

2213
	if (server_use_pipes)
2214
	{
2215
		/* only a single gdb connection when using a pipe */
2216

2217
2218
2219
		gdb_service = malloc(sizeof(gdb_service_t));
		gdb_service->target = target;

2220
		add_service("gdb", CONNECTION_PIPE, 0, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
2221

zwelch's avatar
zwelch committed
2222
2223
		LOG_DEBUG("gdb service for target %s using pipes",
				target_get_name(target));
2224
	}
2225
2226
2227
2228
2229
2230
	else
	{
		while (target)
		{
			gdb_service = malloc(sizeof(gdb_service_t));
			gdb_service->target = target;
2231

2232
			add_service("gdb", CONNECTION_TCP, gdb_port + target->target_number, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
2233

zwelch's avatar
zwelch committed
2234
2235
2236
			LOG_DEBUG("gdb service for target %s at port %i",
					target_get_name(target),
					gdb_port + target->target_number);
2237
2238
2239
			target = target->next;
		}
	}
2240

2241
2242
2243
2244
2245
2246
2247
	return ERROR_OK;
}

/* daemon configuration command gdb_port */
int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc == 0)
oharboe's avatar
oharboe committed
2248
	{
oharboe's avatar
oharboe committed
2249
		command_print(cmd_ctx, "%d", gdb_port);
2250
		return ERROR_OK;
oharboe's avatar
oharboe committed
2251
	}
2252

ntfreak's avatar
ntfreak committed
2253
	gdb_port = strtoul(args[0], NULL, 0);
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281

	return ERROR_OK;
}

int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc == 1)
	{
		if (strcmp(args[0], "resume") == 0)
		{
			detach_mode = GDB_DETACH_RESUME;
			return ERROR_OK;
		}
		else if (strcmp(args[0], "reset") == 0)
		{
			detach_mode = GDB_DETACH_RESET;
			return ERROR_OK;
		}
		else if (strcmp(args[0], "halt") == 0)
		{
			detach_mode = GDB_DETACH_HALT;
			return ERROR_OK;
		}
		else if (strcmp(args[0], "nothing") == 0)
		{
			detach_mode = GDB_DETACH_NOTHING;
			return ERROR_OK;
		}
oharboe's avatar
oharboe committed
2282
2283
		else
			LOG_WARNING("invalid gdb_detach configuration directive: %s", args[0]);
2284
	}
ntfreak's avatar
ntfreak committed
2285

oharboe's avatar
oharboe committed
2286
	return ERROR_COMMAND_SYNTAX_ERROR;
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
}

int handle_gdb_memory_map_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc == 1)
	{
		if (strcmp(args[0], "enable") == 0)
		{
			gdb_use_memory_map = 1;
			return ERROR_OK;
		}
		else if (strcmp(args[0], "disable") == 0)
		{
			gdb_use_memory_map = 0;
			return ERROR_OK;
		}
oharboe's avatar
oharboe committed
2303
2304
		else
			LOG_WARNING("invalid gdb_memory_map configuration directive %s", args[0]);
2305
	}
ntfreak's avatar
ntfreak committed
2306

oharboe's avatar
oharboe committed
2307
	return ERROR_COMMAND_SYNTAX_ERROR;
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
}

int handle_gdb_flash_program_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc == 1)
	{
		if (strcmp(args[0], "enable") == 0)
		{
			gdb_flash_program = 1;
			return ERROR_OK;
		}
		else if (strcmp(args[0], "disable") == 0)
		{
			gdb_flash_program = 0;
			return ERROR_OK;
		}
oharboe's avatar
oharboe committed
2324
2325
		else
			LOG_WARNING("invalid gdb_flash_program configuration directive: %s", args[0]);
2326
	}
ntfreak's avatar
ntfreak committed
2327

oharboe's avatar
oharboe committed
2328
	return ERROR_COMMAND_SYNTAX_ERROR;
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
}

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;
		}
oharboe's avatar
oharboe committed
2345
2346
		else
			LOG_WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
2347
	}
ntfreak's avatar
ntfreak committed
2348

oharboe's avatar
oharboe committed
2349
	return ERROR_COMMAND_SYNTAX_ERROR;
2350
2351
}

oharboe's avatar
oharboe committed
2352
/* gdb_breakpoint_override */
2353
2354
2355
2356
int handle_gdb_breakpoint_override_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc == 0)
	{
2357

zwelch's avatar
zwelch committed
2358
	} else if (argc == 1)
2359
2360
	{
		gdb_breakpoint_override = 1;
zwelch's avatar
zwelch committed
2361
		if (strcmp(args[0], "hard") == 0)
2362
		{
zwelch's avatar
zwelch committed
2363
			gdb_breakpoint_override_type = BKPT_HARD;
zwelch's avatar
zwelch committed
2364
		} else if (strcmp(args[0], "soft") == 0)
2365
		{
zwelch's avatar
zwelch committed
2366
			gdb_breakpoint_override_type = BKPT_SOFT;
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
		} else if (strcmp(args[0], "disable") == 0)
		{
			gdb_breakpoint_override = 0;
		}
	} else
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
	}
	if (gdb_breakpoint_override)
	{
zwelch's avatar
zwelch committed
2377
		LOG_USER("force %s breakpoints", (gdb_breakpoint_override_type == BKPT_HARD)?"hard":"soft");
2378
2379
2380
2381
	} else
	{
		LOG_USER("breakpoint type is not overriden");
	}
2382

2383
2384
2385
	return ERROR_OK;
}

2386
2387
2388
int gdb_register_commands(command_context_t *command_context)
{
	register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
2389
			COMMAND_ANY, "daemon configuration command gdb_port");
2390
	register_command(command_context, NULL, "gdb_detach", handle_gdb_detach_command,
zwelch's avatar
zwelch committed
2391
2392
			COMMAND_CONFIG, "resume/reset/halt/nothing - "
			"specify behavior when GDB detaches from the target");
2393
	register_command(command_context, NULL, "gdb_memory_map", handle_gdb_memory_map_command,
oharboe's avatar
oharboe committed
2394
			COMMAND_CONFIG, "enable or disable memory map");
2395
	register_command(command_context, NULL, "gdb_flash_program", handle_gdb_flash_program_command,
oharboe's avatar
oharboe committed
2396
			COMMAND_CONFIG, "enable or disable flash program");
2397
	register_command(command_context, NULL, "gdb_report_data_abort", handle_gdb_report_data_abort_command,
zwelch's avatar
zwelch committed
2398
			COMMAND_CONFIG, "enable or disable reporting data aborts");
2399
	register_command(command_context, NULL, "gdb_breakpoint_override", handle_gdb_breakpoint_override_command,
zwelch's avatar
zwelch committed
2400
			COMMAND_EXEC, "hard/soft/disable - force breakpoint type for gdb 'break' commands.");
2401
2402
	return ERROR_OK;
}
For faster browsing, not all history is shown. View entire blame