blob: 7f2e5c908d0acc48336b3da48e5fed4dda7bc728 [file] [log] [blame]
sewardj3b290482011-05-06 21:02:55 +00001/* Main code for remote server for GDB.
2 Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003,
3 2004, 2005, 2006, 2011
4 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7 It has been modified to integrate it in valgrind
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
23
24#include "server.h"
25#include "regdef.h"
26#include "pub_core_options.h"
27#include "pub_core_translate.h"
28#include "pub_core_mallocfree.h"
sewardj2a312392011-06-26 09:26:48 +000029#include "pub_core_initimg.h"
philippef3a6e932013-01-10 20:42:51 +000030#include "pub_core_execontext.h"
floriandbb35842012-10-27 18:39:11 +000031#include "pub_core_syswrap.h" // VG_(show_open_fds)
philippe66e4c732013-01-26 16:45:01 +000032#include "pub_core_scheduler.h"
philippe8587b542013-12-15 20:24:43 +000033#include "pub_core_transtab.h"
philippe07c08522014-05-14 20:39:27 +000034#include "pub_core_debuginfo.h"
35#include "pub_core_addrinfo.h"
sewardj3b290482011-05-06 21:02:55 +000036
37unsigned long cont_thread;
38unsigned long general_thread;
39unsigned long step_thread;
40unsigned long thread_from_wait;
41unsigned long old_thread_from_wait;
42
philippe886fde32012-03-29 21:56:47 +000043int pass_signals[TARGET_SIGNAL_LAST]; /* indexed by gdb signal nr */
bart2dafc542011-05-18 16:08:28 +000044
sewardj3b290482011-05-06 21:02:55 +000045/* for a gdbserver integrated in valgrind, resuming the process consists
46 in returning the control to valgrind.
philippe349a3912012-05-23 21:50:36 +000047 The guess process resumes its execution.
sewardj3b290482011-05-06 21:02:55 +000048 Then at the next error or break or ..., valgrind calls gdbserver again.
philippe349a3912012-05-23 21:50:36 +000049 A resume reply packet must then be built to inform GDB that the
50 resume request is finished.
51 resume_reply_packet_needed records the fact that the next call to gdbserver
sewardj3b290482011-05-06 21:02:55 +000052 must send a resume packet to gdb. */
philippe349a3912012-05-23 21:50:36 +000053static Bool resume_reply_packet_needed = False;
sewardj3b290482011-05-06 21:02:55 +000054
55VG_MINIMAL_JMP_BUF(toplevel);
56
57/* Decode a qXfer read request. Return 0 if everything looks OK,
58 or -1 otherwise. */
59
60static
florian6bd9dc12012-11-23 16:17:43 +000061int decode_xfer_read (char *buf, const char **annex, CORE_ADDR *ofs, unsigned int *len)
sewardj3b290482011-05-06 21:02:55 +000062{
63 /* Extract and NUL-terminate the annex. */
64 *annex = buf;
65 while (*buf && *buf != ':')
66 buf++;
67 if (*buf == '\0')
68 return -1;
69 *buf++ = 0;
70
71 /* After the read/write marker and annex, qXfer looks like a
72 traditional 'm' packet. */
73 decode_m_packet (buf, ofs, len);
74
75 return 0;
76}
77
78/* Write the response to a successful qXfer read. Returns the
79 length of the (binary) data stored in BUF, corresponding
80 to as much of DATA/LEN as we could fit. IS_MORE controls
81 the first character of the response. */
82static
83int write_qxfer_response (char *buf, unsigned char *data, int len, int is_more)
84{
85 int out_len;
86
87 if (is_more)
88 buf[0] = 'm';
89 else
90 buf[0] = 'l';
91
92 return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len,
93 PBUFSIZ - POVERHSIZ - 1) + 1;
94}
95
96static Bool initial_valgrind_sink_saved = False;
97/* True <=> valgrind log sink saved in initial_valgrind_sink */
98static OutputSink initial_valgrind_sink;
99
100static Bool command_output_to_log = False;
101/* True <=> command output goes to log instead of gdb */
102
florian6bd9dc12012-11-23 16:17:43 +0000103void reset_valgrind_sink(const char *info)
sewardj3b290482011-05-06 21:02:55 +0000104{
105 if (VG_(log_output_sink).fd != initial_valgrind_sink.fd
106 && initial_valgrind_sink_saved) {
107 VG_(log_output_sink).fd = initial_valgrind_sink.fd;
108 VG_(umsg) ("Reset valgrind output to log (%s)\n",
109 (info = NULL ? "" : info));
110 }
111}
112
philippe46207652013-01-20 17:11:58 +0000113void print_to_initial_valgrind_sink (const char *msg)
114{
115 vg_assert (initial_valgrind_sink_saved);
116 VG_(write) (initial_valgrind_sink.fd, msg, strlen(msg));
117}
118
119
sewardj3b290482011-05-06 21:02:55 +0000120static
florian6bd9dc12012-11-23 16:17:43 +0000121void kill_request (const char *msg)
sewardj3b290482011-05-06 21:02:55 +0000122{
123 VG_(umsg) ("%s", msg);
sewardj3b290482011-05-06 21:02:55 +0000124 VG_(exit) (0);
125}
126
philippe02ea4132013-09-04 21:42:43 +0000127// s is a NULL terminated string made of O or more words (separated by spaces).
128// Returns a pointer to the Nth word in s.
129// If Nth word does not exist, return a pointer to the last (0) byte of s.
130static
131const char *wordn (const char *s, int n)
132{
133 int word_seen = 0;
134 Bool searching_word = True;
135
136 while (*s) {
137 if (*s == ' ')
138 searching_word = True;
139 else {
140 if (searching_word) {
141 searching_word = False;
142 word_seen++;
143 if (word_seen == n)
144 return s;
145 }
146 }
147 s++;
148 }
149 return s;
150}
151
philippe4f6f3362014-04-19 00:25:54 +0000152void VG_(print_all_stats) (Bool memory_stats, Bool tool_stats)
153{
154 if (memory_stats) {
155 VG_(message)(Vg_DebugMsg, "\n");
156 VG_(message)(Vg_DebugMsg,
157 "------ Valgrind's internal memory use stats follow ------\n" );
158 VG_(sanity_check_malloc_all)();
159 VG_(message)(Vg_DebugMsg, "------\n" );
160 VG_(print_all_arena_stats)();
161 if (VG_(clo_profile_heap))
162 VG_(print_arena_cc_analysis) ();
163 VG_(message)(Vg_DebugMsg, "\n");
164 }
165
166 VG_(print_translation_stats)();
167 VG_(print_tt_tc_stats)();
168 VG_(print_scheduler_stats)();
169 VG_(print_ExeContext_stats)( False /* with_stacktraces */ );
170 VG_(print_errormgr_stats)();
171 if (tool_stats && VG_(needs).print_stats) {
172 VG_TDICT_CALL(tool_print_stats);
173 }
174}
175
sewardj3b290482011-05-06 21:02:55 +0000176/* handle_gdb_valgrind_command handles the provided mon string command.
177 If command is recognised, return 1 else return 0.
178 Note that in case of ambiguous command, 1 is returned.
179
180 *sink_wanted_at_return is modified if one of the commands
sewardj30b3eca2011-06-28 08:20:39 +0000181 'v.set *_output' is handled.
sewardj3b290482011-05-06 21:02:55 +0000182*/
183static
philippe02ea4132013-09-04 21:42:43 +0000184int handle_gdb_valgrind_command (char *mon, OutputSink *sink_wanted_at_return)
sewardj3b290482011-05-06 21:02:55 +0000185{
186 UWord ret = 0;
187 char s[strlen(mon)+1]; /* copy for strtok_r */
philippe02ea4132013-09-04 21:42:43 +0000188 char *wcmd;
189 HChar *ssaveptr;
190 const char *endptr;
sewardj3b290482011-05-06 21:02:55 +0000191 int kwdid;
192 int int_value;
193
194 vg_assert (initial_valgrind_sink_saved);
195
196 strcpy (s, mon);
197 wcmd = strtok_r (s, " ", &ssaveptr);
198 /* NB: if possible, avoid introducing a new command below which
sewardj30b3eca2011-06-28 08:20:39 +0000199 starts with the same 3 first letters as an already existing
sewardj3b290482011-05-06 21:02:55 +0000200 command. This ensures a shorter abbreviation for the user. */
philippe6ec8d632013-01-23 22:10:28 +0000201 switch (VG_(keyword_id) ("help v.set v.info v.wait v.kill v.translate"
202 " v.do",
sewardj3b290482011-05-06 21:02:55 +0000203 wcmd, kwd_report_duplicated_matches)) {
204 case -2:
205 ret = 1;
206 break;
207 case -1:
208 break;
209 case 0: /* help */
210 ret = 1;
211 wcmd = strtok_r (NULL, " ", &ssaveptr);
212 if (wcmd == NULL) {
213 int_value = 0;
214 } else {
215 switch (VG_(keyword_id) ("debug", wcmd, kwd_report_all)) {
216 case -2: int_value = 0; break;
217 case -1: int_value = 0; break;
218 case 0: int_value = 1; break;
floriane2800c92014-09-15 20:57:45 +0000219 default: vg_assert (0);
sewardj3b290482011-05-06 21:02:55 +0000220 }
221 }
222
223 VG_(gdb_printf) (
224"general valgrind monitor commands:\n"
philippec3360382012-10-21 14:37:14 +0000225" help [debug] : monitor command help. With debug: + debugging commands\n"
sewardj30b3eca2011-06-28 08:20:39 +0000226" v.wait [<ms>] : sleep <ms> (default 0) then continue\n"
227" v.info all_errors : show all errors found so far\n"
228" v.info last_error : show last error found\n"
philippe07c08522014-05-14 20:39:27 +0000229" v.info location <addr> : show information about location <addr>\n"
philippe02ea4132013-09-04 21:42:43 +0000230" v.info n_errs_found [msg] : show the nr of errors found so far and the given msg\n"
philippec3360382012-10-21 14:37:14 +0000231" v.info open_fds : show open file descriptors (only if --track-fds=yes)\n"
sewardj30b3eca2011-06-28 08:20:39 +0000232" v.kill : kill the Valgrind process\n"
233" v.set gdb_output : set valgrind output to gdb\n"
234" v.set log_output : set valgrind output to log\n"
235" v.set mixed_output : set valgrind output to log, interactive output to gdb\n"
philippe46207652013-01-20 17:11:58 +0000236" v.set merge-recursive-frames <num> : merge recursive calls in max <num> frames\n"
sewardj30b3eca2011-06-28 08:20:39 +0000237" v.set vgdb-error <errornr> : debug me at error >= <errornr> \n");
sewardj3b290482011-05-06 21:02:55 +0000238 if (int_value) { VG_(gdb_printf) (
239"debugging valgrind internals monitor commands:\n"
philippe6ec8d632013-01-23 22:10:28 +0000240" v.do expensive_sanity_check_general : do an expensive sanity check now\n"
sewardj30b3eca2011-06-28 08:20:39 +0000241" v.info gdbserver_status : show gdbserver status\n"
philippe93a6a8d2012-04-27 22:59:43 +0000242" v.info memory [aspacemgr] : show valgrind heap memory stats\n"
243" (with aspacemgr arg, also shows valgrind segments on log ouput)\n"
philippef3a6e932013-01-10 20:42:51 +0000244" v.info exectxt : show stacktraces and stats of all execontexts\n"
sewardjd6e13d82011-10-22 20:23:30 +0000245" v.info scheduler : show valgrind thread state and stacktrace\n"
philippe8587b542013-12-15 20:24:43 +0000246" v.info stats : show various valgrind and tool stats\n"
sewardj30b3eca2011-06-28 08:20:39 +0000247" v.set debuglog <level> : set valgrind debug log level to <level>\n"
philippe180a7502014-04-20 13:41:10 +0000248" v.set hostvisibility [yes*|no] : (en/dis)ables access by gdb/gdbserver to\n"
249" Valgrind internal host status/memory\n"
sewardj30b3eca2011-06-28 08:20:39 +0000250" v.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>\n"
sewardj3b290482011-05-06 21:02:55 +0000251" (default traceflags 0b00100000 : show after instrumentation)\n"
252" An additional flag 0b100000000 allows to show gdbserver instrumentation\n");
253 }
254 break;
sewardj30b3eca2011-06-28 08:20:39 +0000255 case 1: /* v.set */
sewardj3b290482011-05-06 21:02:55 +0000256 ret = 1;
257 wcmd = strtok_r (NULL, " ", &ssaveptr);
258 switch (kwdid = VG_(keyword_id)
philippe46207652013-01-20 17:11:58 +0000259 ("vgdb-error debuglog merge-recursive-frames"
philippe64ba5742014-06-19 20:33:27 +0000260 " gdb_output log_output mixed_output hostvisibility",
sewardj3b290482011-05-06 21:02:55 +0000261 wcmd, kwd_report_all)) {
262 case -2:
263 case -1:
264 break;
265 case 0: /* vgdb-error */
266 case 1: /* debuglog */
philippe46207652013-01-20 17:11:58 +0000267 case 2: /* merge-recursive-frames */
sewardj3b290482011-05-06 21:02:55 +0000268 wcmd = strtok_r (NULL, " ", &ssaveptr);
269 if (wcmd == NULL) {
270 int_value = 0;
271 endptr = "empty"; /* to report an error below */
272 } else {
florian6bd9dc12012-11-23 16:17:43 +0000273 HChar *the_end;
274 int_value = strtol (wcmd, &the_end, 10);
275 endptr = the_end;
sewardj3b290482011-05-06 21:02:55 +0000276 }
277 if (*endptr != '\0') {
278 VG_(gdb_printf) ("missing or malformed integer value\n");
279 } else if (kwdid == 0) {
philippe02ea4132013-09-04 21:42:43 +0000280 VG_(printf) ("vgdb-error value changed from %d to %d\n",
sewardj3b290482011-05-06 21:02:55 +0000281 VG_(dyn_vgdb_error), int_value);
282 VG_(dyn_vgdb_error) = int_value;
283 } else if (kwdid == 1) {
philippe02ea4132013-09-04 21:42:43 +0000284 VG_(printf) ("debuglog value changed from %d to %d\n",
sewardj3b290482011-05-06 21:02:55 +0000285 VG_(debugLog_getLevel)(), int_value);
286 VG_(debugLog_startup) (int_value, "gdbsrv");
philippe46207652013-01-20 17:11:58 +0000287 } else if (kwdid == 2) {
philippe02ea4132013-09-04 21:42:43 +0000288 VG_(printf)
philippe46207652013-01-20 17:11:58 +0000289 ("merge-recursive-frames value changed from %d to %d\n",
290 VG_(clo_merge_recursive_frames), int_value);
291 VG_(clo_merge_recursive_frames) = int_value;
sewardj3b290482011-05-06 21:02:55 +0000292 } else {
293 vg_assert (0);
294 }
295 break;
philippe46207652013-01-20 17:11:58 +0000296 case 3: /* gdb_output */
sewardj3b290482011-05-06 21:02:55 +0000297 (*sink_wanted_at_return).fd = -2;
298 command_output_to_log = False;
299 VG_(gdb_printf) ("valgrind output will go to gdb\n");
300 break;
philippe46207652013-01-20 17:11:58 +0000301 case 4: /* log_output */
sewardj3b290482011-05-06 21:02:55 +0000302 (*sink_wanted_at_return).fd = initial_valgrind_sink.fd;
303 command_output_to_log = True;
304 VG_(gdb_printf) ("valgrind output will go to log\n");
305 break;
philippe46207652013-01-20 17:11:58 +0000306 case 5: /* mixed output */
sewardj3b290482011-05-06 21:02:55 +0000307 (*sink_wanted_at_return).fd = initial_valgrind_sink.fd;
308 command_output_to_log = False;
309 VG_(gdb_printf)
310 ("valgrind output will go to log, interactive output will go to gdb\n");
311 break;
philippe180a7502014-04-20 13:41:10 +0000312 case 6: /* hostvisibility */
313 wcmd = strtok_r (NULL, " ", &ssaveptr);
314 if (wcmd != NULL) {
315 switch (VG_(keyword_id) ("yes no", wcmd, kwd_report_all)) {
316 case -2:
317 case -1: break;
318 case 0:
319 hostvisibility = True;
320 break;
321 case 1:
322 hostvisibility = False;
323 break;
floriane2800c92014-09-15 20:57:45 +0000324 default: vg_assert (0);
philippe180a7502014-04-20 13:41:10 +0000325 }
326 } else {
327 hostvisibility = True;
328 }
philippe3a73b392014-06-09 15:47:46 +0000329 if (hostvisibility) {
philippe72a10e52014-07-31 21:15:42 +0000330 const DebugInfo *tooldi
331 = VG_(find_DebugInfo) ((Addr)handle_gdb_valgrind_command);
332 const NSegment *toolseg
333 = tooldi ?
334 VG_(am_find_nsegment) (VG_(DebugInfo_get_text_avma) (tooldi))
335 : NULL;
philippe180a7502014-04-20 13:41:10 +0000336 VG_(gdb_printf)
337 ("Enabled access to Valgrind memory/status by GDB\n"
philippe3a73b392014-06-09 15:47:46 +0000338 "If not yet done, tell GDB which valgrind file(s) to use, "
339 "typically:\n"
philippe72a10e52014-07-31 21:15:42 +0000340 "add-symbol-file %s %p\n",
341 toolseg ? VG_(am_get_filename)(toolseg)
342 : "<toolfile> <address> e.g.",
343 toolseg ? (void*)toolseg->start : (void*)0x38000000);
philippe3a73b392014-06-09 15:47:46 +0000344 } else
philippe180a7502014-04-20 13:41:10 +0000345 VG_(gdb_printf)
346 ("Disabled access to Valgrind memory/status by GDB\n");
347 break;
sewardj3b290482011-05-06 21:02:55 +0000348 default:
349 vg_assert (0);
350 }
351 break;
sewardj30b3eca2011-06-28 08:20:39 +0000352 case 2: /* v.info */ {
sewardj3b290482011-05-06 21:02:55 +0000353 ret = 1;
354 wcmd = strtok_r (NULL, " ", &ssaveptr);
355 switch (kwdid = VG_(keyword_id)
sewardjd6e13d82011-10-22 20:23:30 +0000356 ("all_errors n_errs_found last_error gdbserver_status memory"
philippe07c08522014-05-14 20:39:27 +0000357 " scheduler stats open_fds exectxt location",
sewardj3b290482011-05-06 21:02:55 +0000358 wcmd, kwd_report_all)) {
359 case -2:
360 case -1:
361 break;
362 case 0: // all_errors
363 // A verbosity of minimum 2 is needed to show the errors.
364 VG_(show_all_errors)(/* verbosity */ 2, /* xml */ False);
365 break;
366 case 1: // n_errs_found
philippe02ea4132013-09-04 21:42:43 +0000367 VG_(printf) ("n_errs_found %d n_errs_shown %d (vgdb-error %d) %s\n",
368 VG_(get_n_errs_found) (),
369 VG_(get_n_errs_shown) (),
370 VG_(dyn_vgdb_error),
371 wordn (mon, 3));
sewardj3b290482011-05-06 21:02:55 +0000372 break;
373 case 2: // last_error
374 VG_(show_last_error)();
375 break;
376 case 3: // gdbserver_status
377 VG_(gdbserver_status_output)();
378 break;
379 case 4: /* memory */
philippe8587b542013-12-15 20:24:43 +0000380 VG_(printf) ("%llu bytes have already been allocated.\n",
381 VG_(am_get_anonsize_total)());
sewardj3b290482011-05-06 21:02:55 +0000382 VG_(print_all_arena_stats) ();
383 if (VG_(clo_profile_heap))
384 VG_(print_arena_cc_analysis) ();
philippe93a6a8d2012-04-27 22:59:43 +0000385 wcmd = strtok_r (NULL, " ", &ssaveptr);
386 if (wcmd != NULL) {
387 switch (VG_(keyword_id) ("aspacemgr", wcmd, kwd_report_all)) {
388 case -2:
389 case -1: break;
390 case 0:
391 VG_(am_show_nsegments) (0, "gdbserver v.info memory aspacemgr");
392 break;
floriane2800c92014-09-15 20:57:45 +0000393 default: vg_assert (0);
philippe93a6a8d2012-04-27 22:59:43 +0000394 }
395 }
396
sewardj3b290482011-05-06 21:02:55 +0000397 ret = 1;
398 break;
sewardjd6e13d82011-10-22 20:23:30 +0000399 case 5: /* scheduler */
philippe4f6f3362014-04-19 00:25:54 +0000400 VG_(show_sched_status) (True, // host_stacktrace
philippe38a74d22014-08-29 22:53:19 +0000401 True, // stack_usage
philippe4f6f3362014-04-19 00:25:54 +0000402 True); // exited_threads
sewardjd6e13d82011-10-22 20:23:30 +0000403 ret = 1;
404 break;
philippe8587b542013-12-15 20:24:43 +0000405 case 6: /* stats */
philippe4f6f3362014-04-19 00:25:54 +0000406 VG_(print_all_stats)(False, /* Memory stats */
407 True /* Tool stats */);
philippe8587b542013-12-15 20:24:43 +0000408 ret = 1;
409 break;
410 case 7: /* open_fds */
philippec3360382012-10-21 14:37:14 +0000411 if (VG_(clo_track_fds))
412 VG_(show_open_fds) ("");
413 else
414 VG_(gdb_printf)
415 ("Valgrind must be started with --track-fds=yes"
416 " to show open fds\n");
417 ret = 1;
418 break;
philippe8587b542013-12-15 20:24:43 +0000419 case 8: /* exectxt */
philippef3a6e932013-01-10 20:42:51 +0000420 VG_(print_ExeContext_stats) (True /* with_stacktraces */);
421 ret = 1;
422 break;
philippe07c08522014-05-14 20:39:27 +0000423 case 9: { /* location */
424 /* Note: we prefer 'v.info location' and not 'v.info address' as
425 v.info address is inconsistent with the GDB (native)
426 command 'info address' which gives the address for a symbol.
427 GDB equivalent command of 'v.info location' is 'info symbol'. */
428 Addr address;
429 SizeT dummy_sz = 0x1234;
430 if (VG_(strtok_get_address_and_size) (&address, &dummy_sz, &ssaveptr)) {
431 // If tool provides location information, use that.
432 if (VG_(needs).info_location) {
433 VG_TDICT_CALL(tool_info_location, address);
434 }
435 // If tool does not provide location information, use the common one.
436 // Also use the common to compare with tool when debug log is set.
437 if (!VG_(needs).info_location || VG_(debugLog_getLevel)() > 0 ) {
438 AddrInfo ai;
439 ai.tag = Addr_Undescribed;
440 VG_(describe_addr) (address, &ai);
441 VG_(pp_addrinfo) (address, &ai);
442 VG_(clear_addrinfo) (&ai);
443 }
444 }
445 ret = 1;
446 break;
447 }
sewardj3b290482011-05-06 21:02:55 +0000448 default:
449 vg_assert(0);
450 }
451 break;
452 }
sewardj30b3eca2011-06-28 08:20:39 +0000453 case 3: /* v.wait */
sewardj3b290482011-05-06 21:02:55 +0000454 wcmd = strtok_r (NULL, " ", &ssaveptr);
455 if (wcmd != NULL) {
florian6bd9dc12012-11-23 16:17:43 +0000456 int_value = strtol (wcmd, NULL, 10);
philippe02ea4132013-09-04 21:42:43 +0000457 VG_(printf) ("gdbserver: continuing in %d ms ...\n", int_value);
sewardj3b290482011-05-06 21:02:55 +0000458 VG_(poll)(NULL, 0, int_value);
459 }
philippe02ea4132013-09-04 21:42:43 +0000460 VG_(printf) ("gdbserver: continuing after wait ...\n");
sewardj3b290482011-05-06 21:02:55 +0000461 ret = 1;
462 break;
sewardj30b3eca2011-06-28 08:20:39 +0000463 case 4: /* v.kill */
sewardj3b290482011-05-06 21:02:55 +0000464 kill_request ("monitor command request to kill this process\n");
465 break;
sewardj30b3eca2011-06-28 08:20:39 +0000466 case 5: { /* v.translate */
sewardj3b290482011-05-06 21:02:55 +0000467 Addr address;
468 SizeT verbosity = 0x20;
469
470 ret = 1;
471
philippe07c08522014-05-14 20:39:27 +0000472 if (VG_(strtok_get_address_and_size) (&address, &verbosity, &ssaveptr)) {
sewardj3b290482011-05-06 21:02:55 +0000473 /* we need to force the output to log for the translation trace,
474 as low level VEX tracing cannot be redirected to gdb. */
475 int saved_command_output_to_log = command_output_to_log;
476 int saved_fd = VG_(log_output_sink).fd;
477 Bool single_stepping_on_entry = valgrind_single_stepping();
478 int vex_verbosity = verbosity & 0xff;
479 VG_(log_output_sink).fd = initial_valgrind_sink.fd;
480 if ((verbosity & 0x100) && !single_stepping_on_entry) {
481 valgrind_set_single_stepping(True);
482 // to force gdbserver instrumentation.
483 }
sewardj99d61342011-05-17 16:35:11 +0000484# if defined(VGA_arm)
485 // on arm, we need to (potentially) convert this address
486 // to the thumb form.
487 address = thumb_pc (address);
488# endif
489
sewardj3b290482011-05-06 21:02:55 +0000490 VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
491 address,
492 /*debugging*/True,
493 (Int) vex_verbosity,
494 /*bbs_done*/0,
495 /*allow redir?*/True);
496 if ((verbosity & 0x100) && !single_stepping_on_entry) {
497 valgrind_set_single_stepping(False);
498 // reset single stepping.
499 }
500 command_output_to_log = saved_command_output_to_log;
501 VG_(log_output_sink).fd = saved_fd;
502 }
503 break;
504 }
505
philippe6ec8d632013-01-23 22:10:28 +0000506 case 6: /* v.do */
507 ret = 1;
508 wcmd = strtok_r (NULL, " ", &ssaveptr);
509 switch (VG_(keyword_id) ("expensive_sanity_check_general",
510 wcmd, kwd_report_all)) {
511 case -2:
512 case -1: break;
513 case 0: { /* expensive_sanity_check_general */
514 // Temporarily bump up sanity level to check e.g. the malloc arenas.
515 const Int save_clo_sanity_level = VG_(clo_sanity_level);
516 if (VG_(clo_sanity_level) < 4) VG_(clo_sanity_level) = 4;
517 VG_(sanity_check_general) (/* force_expensive */ True);
518 VG_(clo_sanity_level) = save_clo_sanity_level;
519 break;
520 }
floriane2800c92014-09-15 20:57:45 +0000521 default: vg_assert (0);
philippe6ec8d632013-01-23 22:10:28 +0000522 }
523 break;
524
sewardj3b290482011-05-06 21:02:55 +0000525 default:
526 vg_assert (0);
527 }
528 return ret;
529}
530
531/* handle_gdb_monitor_command handles the provided mon string command,
532 which can be either a "standard" valgrind monitor command
533 or a tool specific monitor command.
534 If command recognised, return 1 else return 0.
535 Note that in case of ambiguous command, 1 is returned.
536*/
537static
philippe02ea4132013-09-04 21:42:43 +0000538int handle_gdb_monitor_command (char *mon)
sewardj3b290482011-05-06 21:02:55 +0000539{
540 UWord ret = 0;
541 UWord tool_ret = 0;
542 // initially, we assume that when returning, the desired sink is the
543 // one we have when entering. It can however be changed by the standard
544 // valgrind command handling.
545 OutputSink sink_wanted_at_return = VG_(log_output_sink);
546
547 if (!initial_valgrind_sink_saved) {
548 /* first time we enter here, we save the valgrind default log sink */
549 initial_valgrind_sink = sink_wanted_at_return;
550 initial_valgrind_sink_saved = True;
551 }
552
553 if (!command_output_to_log)
554 VG_(log_output_sink).fd = -2; /* redirect to monitor_output */
555
556 ret = handle_gdb_valgrind_command (mon, &sink_wanted_at_return);
557
558 /* Even if command was recognised by valgrind core, we call the
559 tool command handler : this is needed to handle help command
560 and/or to let the tool do some additional processing of a
561 valgrind standard command. Note however that if valgrind
562 recognised the command, we will always return success. */
563 if (VG_(needs).client_requests) {
564 /* If the tool reports an error when handling a monitor command,
565 we need to avoid calling gdbserver during this command
566 handling. So, we temporarily set VG_(dyn_vgdb_error) to
567 a huge value to ensure m_errormgr.c does not call gdbserver. */
568 Int save_dyn_vgdb_error = VG_(dyn_vgdb_error);
569 UWord arg[2];
570 VG_(dyn_vgdb_error) = 999999999;
571 arg[0] = (UWord) VG_USERREQ__GDB_MONITOR_COMMAND;
572 arg[1] = (UWord) mon;
573 VG_TDICT_CALL(tool_handle_client_request, VG_(running_tid), arg,
574 &tool_ret);
575 VG_(dyn_vgdb_error) = save_dyn_vgdb_error;
576 }
577
philippe02ea4132013-09-04 21:42:43 +0000578 VG_(message_flush) ();
579
sewardj3b290482011-05-06 21:02:55 +0000580 /* restore or set the desired output */
581 VG_(log_output_sink).fd = sink_wanted_at_return.fd;
582 if (ret | tool_ret)
583 return 1;
584 else
585 return 0;
586}
587
588
589/* Handle all of the extended 'Q' packets. */
590static
591void handle_set (char *arg_own_buf, int *new_packet_len_p)
592{
593 if (strcmp ("QStartNoAckMode", arg_own_buf) == 0) {
594 noack_mode = True;
595 write_ok (arg_own_buf);
596 return;
597 }
598
599 if (strncmp ("QPassSignals:", arg_own_buf, 13) == 0) {
600 int i;
601 char *from, *to;
602 char *end = arg_own_buf + strlen(arg_own_buf);
603 CORE_ADDR sig;
604 for (i = 0; i < TARGET_SIGNAL_LAST; i++)
605 pass_signals[i] = 0;
606
607 from = arg_own_buf + 13;
608 while (from < end) {
609 to = strchr(from, ';');
610 if (to == NULL) to = end;
611 decode_address (&sig, from, to - from);
612 pass_signals[(int)sig] = 1;
philippe886fde32012-03-29 21:56:47 +0000613 dlog(1, "pass_signal gdb_nr %d %s\n",
614 (int)sig, target_signal_to_name(sig));
sewardj3b290482011-05-06 21:02:55 +0000615 from = to;
616 if (*from == ';') from++;
617 }
618 write_ok (arg_own_buf);
619 return;
620 }
621 /* Otherwise we didn't know what packet it was. Say we didn't
622 understand it. */
623 arg_own_buf[0] = 0;
624}
625
philippe02ea4132013-09-04 21:42:43 +0000626Bool VG_(client_monitor_command) (HChar *cmd)
philippe46207652013-01-20 17:11:58 +0000627{
628 const Bool connected = remote_connected();
629 const int saved_command_output_to_log = command_output_to_log;
630 Bool handled;
631
632 if (!connected)
633 command_output_to_log = True;
634 handled = handle_gdb_monitor_command (cmd);
635 if (!connected) {
636 // reset the log output unless cmd changed it.
637 if (command_output_to_log)
638 command_output_to_log = saved_command_output_to_log;
639 }
640 if (handled)
641 return False; // recognised
642 else
643 return True; // not recognised
644}
645
sewardj3b290482011-05-06 21:02:55 +0000646/* Handle all of the extended 'q' packets. */
647static
648void handle_query (char *arg_own_buf, int *new_packet_len_p)
649{
650 static struct inferior_list_entry *thread_ptr;
651
philippe1670b052014-08-15 10:27:52 +0000652 /* thread local storage query */
653 if (strncmp ("qGetTLSAddr:", arg_own_buf, 12) == 0) {
654 char *from, *to;
655 char *end = arg_own_buf + strlen(arg_own_buf);
656 unsigned long gdb_id;
657 CORE_ADDR lm;
658 CORE_ADDR offset;
659 struct thread_info *ti;
660
661 from = arg_own_buf + 12;
662 to = strchr(from, ',');
663 *to = 0;
664 gdb_id = strtoul (from, NULL, 16);
665 from = to + 1;
666 to = strchr(from, ',');
667 decode_address (&offset, from, to - from);
668 from = to + 1;
669 to = end;
670 decode_address (&lm, from, to - from);
671 dlog(2, "qGetTLSAddr thread %lu offset %p lm %p\n",
672 gdb_id, (void*)offset, (void*)lm);
673
674 ti = gdb_id_to_thread (gdb_id);
675 if (ti != NULL) {
676 ThreadState *tst;
677 Addr tls_addr;
678
679 tst = (ThreadState *) inferior_target_data (ti);
680 if (valgrind_get_tls_addr(tst, offset, lm, &tls_addr)) {
681 VG_(sprintf) (arg_own_buf, "%lx", tls_addr);
682 return;
683 }
684 // else we will report we do not support qGetTLSAddr
685 } else {
686 write_enn (arg_own_buf);
687 return;
688 }
689 }
690
sewardj3b290482011-05-06 21:02:55 +0000691 /* qRcmd, monitor command handling. */
692 if (strncmp ("qRcmd,", arg_own_buf, 6) == 0) {
693 char *p = arg_own_buf + 6;
694 int cmdlen = strlen(p)/2;
695 char cmd[cmdlen+1];
696
697 if (unhexify (cmd, p, cmdlen) != cmdlen) {
698 write_enn (arg_own_buf);
699 return;
700 }
701 cmd[cmdlen] = '\0';
702
703 if (handle_gdb_monitor_command (cmd)) {
sewardj3b290482011-05-06 21:02:55 +0000704 write_ok (arg_own_buf);
705 return;
706 } else {
707 /* cmd not recognised */
708 VG_(gdb_printf)
709 ("command '%s' not recognised\n"
710 "In gdb, try 'monitor help'\n"
711 "In a shell, try 'vgdb help'\n",
712 cmd);
713 write_ok (arg_own_buf);
714 return;
715 }
716 }
717
718 /* provide some valgrind specific info in return to qThreadExtraInfo. */
719 if (strncmp ("qThreadExtraInfo,", arg_own_buf, 17) == 0) {
720 unsigned long gdb_id;
721 struct thread_info *ti;
722 ThreadState *tst;
723 char status[100];
724
725 gdb_id = strtoul (&arg_own_buf[17], NULL, 16);
726 ti = gdb_id_to_thread (gdb_id);
727 if (ti != NULL) {
728 tst = (ThreadState *) inferior_target_data (ti);
florian49789512013-09-16 17:08:50 +0000729 /* Additional info is the tid, the thread status and the thread's
730 name, if any. */
731 if (tst->thread_name) {
732 VG_(snprintf) (status, sizeof(status), "tid %d %s %s",
733 tst->tid,
734 VG_(name_of_ThreadStatus)(tst->status),
735 tst->thread_name);
736 } else {
737 VG_(snprintf) (status, sizeof(status), "tid %d %s",
738 tst->tid,
739 VG_(name_of_ThreadStatus)(tst->status));
740 }
sewardj3b290482011-05-06 21:02:55 +0000741 hexify (arg_own_buf, status, strlen(status));
742 return;
743 } else {
744 write_enn (arg_own_buf);
745 return;
746 }
747 }
philippe1670b052014-08-15 10:27:52 +0000748
sewardj3b290482011-05-06 21:02:55 +0000749 if (strcmp ("qAttached", arg_own_buf) == 0) {
750 /* tell gdb to always detach, never kill the process */
751 arg_own_buf[0] = '1';
752 arg_own_buf[1] = 0;
753 return;
754 }
755
756 if (strcmp ("qSymbol::", arg_own_buf) == 0) {
757 /* We have no symbol to read. */
758 write_ok (arg_own_buf);
759 return;
760 }
761
762 if (strcmp ("qfThreadInfo", arg_own_buf) == 0) {
763 thread_ptr = all_threads.head;
764 VG_(sprintf) (arg_own_buf, "m%x",
765 thread_to_gdb_id ((struct thread_info *)thread_ptr));
766 thread_ptr = thread_ptr->next;
767 return;
768 }
769
770 if (strcmp ("qsThreadInfo", arg_own_buf) == 0) {
771 if (thread_ptr != NULL) {
772 VG_(sprintf) (arg_own_buf, "m%x",
773 thread_to_gdb_id ((struct thread_info *)thread_ptr));
774 thread_ptr = thread_ptr->next;
775 return;
776 } else {
777 VG_(sprintf) (arg_own_buf, "l");
778 return;
779 }
780 }
781
philippe419d5f22012-05-24 21:33:17 +0000782 if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL
sewardj3b290482011-05-06 21:02:55 +0000783 && strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
784 CORE_ADDR ofs;
785 unsigned int len, doc_len;
florian6bd9dc12012-11-23 16:17:43 +0000786 const char *annex = NULL;
sewardj3b290482011-05-06 21:02:55 +0000787 // First, the annex is extracted from the packet received.
788 // Then, it is replaced by the corresponding file name.
789 int fd;
790
791 /* Grab the annex, offset, and length. */
792 if (decode_xfer_read (arg_own_buf + 20, &annex, &ofs, &len) < 0) {
793 strcpy (arg_own_buf, "E00");
794 return;
795 }
796
797 if (strcmp (annex, "target.xml") == 0) {
philippe419d5f22012-05-24 21:33:17 +0000798 annex = valgrind_target_xml(VG_(clo_vgdb_shadow_registers));
799 if (annex != NULL && VG_(clo_vgdb_shadow_registers)) {
800 /* Ensure the shadow registers are initialized. */
801 initialize_shadow_low(True);
sewardj3b290482011-05-06 21:02:55 +0000802 }
sewardj3b290482011-05-06 21:02:55 +0000803 if (annex == NULL) {
804 strcpy (arg_own_buf, "E00");
805 return;
806 }
807 }
808
809 {
philippe75a5f782012-02-24 11:25:58 +0000810 char doc[VG_(strlen)(VG_(libdir)) + 1 + VG_(strlen)(annex) + 1];
sewardj3b290482011-05-06 21:02:55 +0000811 struct vg_stat stat_doc;
812 char toread[len];
813 int len_read;
814
815 VG_(sprintf)(doc, "%s/%s", VG_(libdir), annex);
816 fd = VG_(fd_open) (doc, VKI_O_RDONLY, 0);
817 if (fd == -1) {
818 strcpy (arg_own_buf, "E00");
819 return;
820 }
821 if (VG_(fstat) (fd, &stat_doc) != 0) {
822 VG_(close) (fd);
823 strcpy (arg_own_buf, "E00");
824 return;
825 }
826 doc_len = stat_doc.size;
827
828 if (len > PBUFSIZ - POVERHSIZ)
829 len = PBUFSIZ - POVERHSIZ;
830
831 if (ofs > doc_len) {
832 write_enn (arg_own_buf);
833 VG_(close) (fd);
834 return;
835 }
836 VG_(lseek) (fd, ofs, VKI_SEEK_SET);
837 len_read = VG_(read) (fd, toread, len);
florian1636d332012-11-15 04:27:04 +0000838 *new_packet_len_p = write_qxfer_response (arg_own_buf, (unsigned char *)toread,
sewardj3b290482011-05-06 21:02:55 +0000839 len_read, ofs + len_read < doc_len);
840 VG_(close) (fd);
841 return;
842 }
843 }
844
sewardj2a312392011-06-26 09:26:48 +0000845 if (strncmp ("qXfer:auxv:read:", arg_own_buf, 16) == 0) {
846 unsigned char *data;
847 int n;
848 CORE_ADDR ofs;
849 unsigned int len;
florian6bd9dc12012-11-23 16:17:43 +0000850 const char *annex;
sewardj2a312392011-06-26 09:26:48 +0000851
852 /* Reject any annex; grab the offset and length. */
853 if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
854 || annex[0] != '\0') {
855 strcpy (arg_own_buf, "E00");
856 return;
857 }
858
859 if (len > PBUFSIZ - 2)
860 len = PBUFSIZ - 2;
861 data = malloc (len);
862
863 {
864 UWord *client_auxv = VG_(client_auxv);
865 unsigned int client_auxv_len = 0;
866 while (*client_auxv != 0) {
867 dlog(4, "auxv %lld %llx\n",
868 (ULong)*client_auxv,
869 (ULong)*(client_auxv+1));
870 client_auxv++;
871 client_auxv++;
872 client_auxv_len += 2 * sizeof(UWord);
873 }
874 client_auxv_len += 2 * sizeof(UWord);
875 dlog(4, "auxv len %d\n", client_auxv_len);
876
877 if (ofs >= client_auxv_len)
878 n = -1;
879 else {
880 n = client_auxv_len - ofs;
881 VG_(memcpy) (data, (unsigned char *) VG_(client_auxv), n);
882 }
883 }
884
885 if (n < 0)
886 write_enn (arg_own_buf);
887 else if (n > len)
888 *new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1);
889 else
890 *new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0);
891
892 free (data);
893
894 return;
895 }
896
897
sewardj3b290482011-05-06 21:02:55 +0000898 /* Protocol features query. */
899 if (strncmp ("qSupported", arg_own_buf, 10) == 0
900 && (arg_own_buf[10] == ':' || arg_own_buf[10] == '\0')) {
901 VG_(sprintf) (arg_own_buf, "PacketSize=%x", PBUFSIZ - 1);
902 /* Note: max packet size including frame and checksum, but without
903 trailing null byte, which is not sent/received. */
904
905 strcat (arg_own_buf, ";QStartNoAckMode+");
906 strcat (arg_own_buf, ";QPassSignals+");
sewardj2a312392011-06-26 09:26:48 +0000907 if (VG_(client_auxv))
908 strcat (arg_own_buf, ";qXfer:auxv:read+");
sewardj3b290482011-05-06 21:02:55 +0000909
philippe419d5f22012-05-24 21:33:17 +0000910 if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL) {
sewardj3b290482011-05-06 21:02:55 +0000911 strcat (arg_own_buf, ";qXfer:features:read+");
912 /* if a new gdb connects to us, we have to reset the register
913 set to the normal register sets to allow this new gdb to
914 decide to use or not the shadow registers.
915
916 Note that the reset is only done for gdb that are sending
917 qSupported packets. If a user first connected with a recent
918 gdb using shadow registers and then with a very old gdb
919 that does not use qSupported packet, then the old gdb will
920 not properly connect. */
921 initialize_shadow_low(False);
922 }
923 return;
924 }
925
926 /* Otherwise we didn't know what packet it was. Say we didn't
927 understand it. */
928 arg_own_buf[0] = 0;
929}
930
931/* Handle all of the extended 'v' packets. */
932static
sewardj0bb3c672011-07-26 23:29:25 +0000933void handle_v_requests (char *arg_own_buf, char *status, int *zignal)
sewardj3b290482011-05-06 21:02:55 +0000934{
935 /* vcont packet code from gdb 6.6 removed */
936
937 /* Otherwise we didn't know what packet it was. Say we didn't
938 understand it. */
939 arg_own_buf[0] = 0;
940 return;
941}
942
943static
944void myresume (int step, int sig)
945{
946 struct thread_resume resume_info[2];
947 int n = 0;
948
philippe349a3912012-05-23 21:50:36 +0000949 if (step || sig) {
sewardj3b290482011-05-06 21:02:55 +0000950 resume_info[0].step = step;
951 resume_info[0].sig = sig;
sewardj3b290482011-05-06 21:02:55 +0000952 n++;
953 }
sewardj3b290482011-05-06 21:02:55 +0000954 resume_info[n].step = 0;
955 resume_info[n].sig = 0;
sewardj3b290482011-05-06 21:02:55 +0000956
philippe349a3912012-05-23 21:50:36 +0000957 resume_reply_packet_needed = True;
958 valgrind_resume (resume_info);
sewardj3b290482011-05-06 21:02:55 +0000959}
960
961/* server_main global variables */
962static char *own_buf;
963static unsigned char *mem_buf;
964
965void gdbserver_init (void)
966{
967 dlog(1, "gdbserver_init gdbserver embedded in valgrind: %s\n", version);
968 noack_mode = False;
philippe349a3912012-05-23 21:50:36 +0000969 valgrind_initialize_target ();
philippe0e1cac92012-02-28 22:37:44 +0000970 // After a fork, gdbserver_init can be called again.
971 // We do not have to re-malloc the buffers in such a case.
972 if (own_buf == NULL)
philippe03ffc6e2013-07-25 22:37:02 +0000973 own_buf = malloc (PBUFSIZ+POVERHSIZ);
philippe0e1cac92012-02-28 22:37:44 +0000974 if (mem_buf == NULL)
philippe03ffc6e2013-07-25 22:37:02 +0000975 mem_buf = malloc (PBUFSIZ+POVERHSIZ);
976 // Note: normally, we should only malloc PBUFSIZ. However,
977 // GDB has a bug, and in some cases, sends e.g. 'm' packets
978 // asking for slightly more than the PacketSize given at
979 // connection initialisation. So, we bypass the GDB bug
980 // by allocating slightly more.
sewardj3b290482011-05-06 21:02:55 +0000981}
982
983void gdbserver_terminate (void)
984{
985 /* last call to gdbserver is cleanup call */
986 if (VG_MINIMAL_SETJMP(toplevel)) {
987 dlog(0, "error caused VG_MINIMAL_LONGJMP to gdbserver_terminate\n");
988 return;
989 }
990 remote_close();
991}
992
993void server_main (void)
994{
995 static char status;
sewardj0bb3c672011-07-26 23:29:25 +0000996 static int zignal;
sewardj3b290482011-05-06 21:02:55 +0000997
998 char ch;
999 int i = 0;
1000 unsigned int len;
1001 CORE_ADDR mem_addr;
1002
philippe349a3912012-05-23 21:50:36 +00001003 zignal = valgrind_wait (&status);
sewardj3b290482011-05-06 21:02:55 +00001004 if (VG_MINIMAL_SETJMP(toplevel)) {
1005 dlog(0, "error caused VG_MINIMAL_LONGJMP to server_main\n");
1006 }
1007 while (1) {
1008 unsigned char sig;
1009 int packet_len;
1010 int new_packet_len = -1;
1011
philippe349a3912012-05-23 21:50:36 +00001012 if (resume_reply_packet_needed) {
1013 /* Send the resume reply to reply to last GDB resume
1014 request. */
1015 resume_reply_packet_needed = False;
sewardj0bb3c672011-07-26 23:29:25 +00001016 prepare_resume_reply (own_buf, status, zignal);
sewardj3b290482011-05-06 21:02:55 +00001017 putpkt (own_buf);
1018 }
1019
philippe0447bbd2012-10-17 21:32:03 +00001020 /* If we our status is terminal (exit or fatal signal) get out
1021 as quickly as we can. We won't be able to handle any request
1022 anymore. */
1023 if (status == 'W' || status == 'X') {
1024 return;
1025 }
1026
sewardj3b290482011-05-06 21:02:55 +00001027 packet_len = getpkt (own_buf);
1028 if (packet_len <= 0)
1029 break;
1030
1031 i = 0;
1032 ch = own_buf[i++];
1033 switch (ch) {
1034 case 'Q':
1035 handle_set (own_buf, &new_packet_len);
1036 break;
1037 case 'q':
1038 handle_query (own_buf, &new_packet_len);
1039 break;
1040 case 'd':
1041 /* set/unset debugging is done through valgrind debug level. */
1042 own_buf[0] = '\0';
1043 break;
1044 case 'D':
1045 reset_valgrind_sink("gdb detaching from process");
1046
1047 /* When detaching or kill the process, gdb expects to get
1048 an packet OK back. Any other output will make gdb
1049 believes detach did not work. */
1050 write_ok (own_buf);
1051 putpkt (own_buf);
1052 remote_finish (reset_after_error);
1053 remote_open (VG_(clo_vgdb_prefix));
1054 myresume (0, 0);
philippe349a3912012-05-23 21:50:36 +00001055 resume_reply_packet_needed = False;
sewardj3b290482011-05-06 21:02:55 +00001056 return;
1057 case '!':
1058 /* We can not use the extended protocol with valgrind,
1059 because we can not restart the running
1060 program. So return unrecognized. */
1061 own_buf[0] = '\0';
1062 break;
1063 case '?':
sewardj0bb3c672011-07-26 23:29:25 +00001064 prepare_resume_reply (own_buf, status, zignal);
sewardj3b290482011-05-06 21:02:55 +00001065 break;
1066 case 'H':
1067 if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') {
1068 unsigned long gdb_id, thread_id;
1069
1070 gdb_id = strtoul (&own_buf[2], NULL, 16);
1071 thread_id = gdb_id_to_thread_id (gdb_id);
1072 if (thread_id == 0) {
1073 write_enn (own_buf);
1074 break;
1075 }
1076
1077 if (own_buf[1] == 'g') {
1078 general_thread = thread_id;
1079 set_desired_inferior (1);
1080 } else if (own_buf[1] == 'c') {
1081 cont_thread = thread_id;
1082 } else if (own_buf[1] == 's') {
1083 step_thread = thread_id;
1084 }
1085
1086 write_ok (own_buf);
1087 } else {
1088 /* Silently ignore it so that gdb can extend the protocol
1089 without compatibility headaches. */
1090 own_buf[0] = '\0';
1091 }
1092 break;
1093 case 'g':
1094 set_desired_inferior (1);
1095 registers_to_string (own_buf);
1096 break;
1097 case 'G':
1098 set_desired_inferior (1);
1099 registers_from_string (&own_buf[1]);
1100 write_ok (own_buf);
1101 break;
1102 case 'P': {
1103 int regno;
1104 char *regbytes;
1105 Bool mod;
1106 ThreadState *tst;
1107 regno = strtol(&own_buf[1], NULL, 16);
1108 regbytes = strchr(&own_buf[0], '=') + 1;
1109 set_desired_inferior (1);
1110 tst = (ThreadState *) inferior_target_data (current_inferior);
1111 /* Only accept changing registers in "runnable state3.
1112 In fact, it would be ok to change most of the registers
1113 except a few "sensitive" registers such as the PC, SP, BP.
1114 We assume we do not need to very specific here, and that we
1115 can just refuse all of these. */
1116 if (tst->status == VgTs_Runnable || tst->status == VgTs_Yielding) {
1117 supply_register_from_string (regno, regbytes, &mod);
1118 write_ok (own_buf);
1119 } else {
1120 /* at least from gdb 6.6 onwards, an E. error
1121 reply is shown to the user. So, we do an error
1122 msg which both is accepted by gdb as an error msg
1123 and is readable by the user. */
1124 VG_(sprintf)
1125 (own_buf,
1126"E.\n"
1127"ERROR changing register %s regno %d\n"
1128"gdb commands changing registers (pc, sp, ...) (e.g. 'jump',\n"
1129"set pc, calling from gdb a function in the debugged process, ...)\n"
1130"can only be accepted if the thread is VgTs_Runnable or VgTs_Yielding state\n"
1131"Thread status is %s\n",
1132 find_register_by_number (regno)->name, regno,
1133 VG_(name_of_ThreadStatus)(tst->status));
1134 if (VG_(clo_verbosity) > 1)
1135 VG_(umsg) ("%s\n", own_buf);
1136 }
1137 break;
1138 }
1139 case 'm':
1140 decode_m_packet (&own_buf[1], &mem_addr, &len);
philippe349a3912012-05-23 21:50:36 +00001141 if (valgrind_read_memory (mem_addr, mem_buf, len) == 0)
sewardj3b290482011-05-06 21:02:55 +00001142 convert_int_to_ascii (mem_buf, own_buf, len);
1143 else
1144 write_enn (own_buf);
1145 break;
1146 case 'M':
1147 decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
philippe349a3912012-05-23 21:50:36 +00001148 if (valgrind_write_memory (mem_addr, mem_buf, len) == 0)
sewardj3b290482011-05-06 21:02:55 +00001149 write_ok (own_buf);
1150 else
1151 write_enn (own_buf);
1152 break;
1153 case 'X':
1154 if (decode_X_packet (&own_buf[1], packet_len - 1,
1155 &mem_addr, &len, mem_buf) < 0
philippe349a3912012-05-23 21:50:36 +00001156 || valgrind_write_memory (mem_addr, mem_buf, len) != 0)
sewardj3b290482011-05-06 21:02:55 +00001157 write_enn (own_buf);
1158 else
1159 write_ok (own_buf);
1160 break;
1161 case 'C':
1162 convert_ascii_to_int (own_buf + 1, &sig, 1);
1163 if (target_signal_to_host_p (sig))
sewardj0bb3c672011-07-26 23:29:25 +00001164 zignal = target_signal_to_host (sig);
sewardj3b290482011-05-06 21:02:55 +00001165 else
sewardj0bb3c672011-07-26 23:29:25 +00001166 zignal = 0;
sewardj3b290482011-05-06 21:02:55 +00001167 set_desired_inferior (0);
sewardj0bb3c672011-07-26 23:29:25 +00001168 myresume (0, zignal);
sewardj3b290482011-05-06 21:02:55 +00001169 return; // return control to valgrind
1170 case 'S':
1171 convert_ascii_to_int (own_buf + 1, &sig, 1);
1172 if (target_signal_to_host_p (sig))
sewardj0bb3c672011-07-26 23:29:25 +00001173 zignal = target_signal_to_host (sig);
sewardj3b290482011-05-06 21:02:55 +00001174 else
sewardj0bb3c672011-07-26 23:29:25 +00001175 zignal = 0;
sewardj3b290482011-05-06 21:02:55 +00001176 set_desired_inferior (0);
sewardj0bb3c672011-07-26 23:29:25 +00001177 myresume (1, zignal);
sewardj3b290482011-05-06 21:02:55 +00001178 return; // return control to valgrind
1179 case 'c':
1180 set_desired_inferior (0);
1181 myresume (0, 0);
1182 return; // return control to valgrind
1183 case 's':
1184 set_desired_inferior (0);
1185 myresume (1, 0);
1186 return; // return control to valgrind
1187 case 'Z': {
1188 char *lenptr;
1189 char *dataptr;
1190 CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
1191 int zlen = strtol (lenptr + 1, &dataptr, 16);
1192 char type = own_buf[1];
1193
philippe349a3912012-05-23 21:50:36 +00001194 if (type < '0' || type > '4') {
1195 /* Watchpoint command type unrecognized. */
sewardj3b290482011-05-06 21:02:55 +00001196 own_buf[0] = '\0';
1197 } else {
1198 int res;
1199
philippe349a3912012-05-23 21:50:36 +00001200 res = valgrind_insert_watchpoint (type, addr, zlen);
sewardj3b290482011-05-06 21:02:55 +00001201 if (res == 0)
1202 write_ok (own_buf);
1203 else if (res == 1)
1204 /* Unsupported. */
1205 own_buf[0] = '\0';
1206 else
1207 write_enn (own_buf);
1208 }
1209 break;
1210 }
1211 case 'z': {
1212 char *lenptr;
1213 char *dataptr;
1214 CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
1215 int zlen = strtol (lenptr + 1, &dataptr, 16);
1216 char type = own_buf[1];
1217
philippe349a3912012-05-23 21:50:36 +00001218 if (type < '0' || type > '4') {
1219 /* Watchpoint command type unrecognized. */
sewardj3b290482011-05-06 21:02:55 +00001220 own_buf[0] = '\0';
1221 } else {
1222 int res;
1223
philippe349a3912012-05-23 21:50:36 +00001224 res = valgrind_remove_watchpoint (type, addr, zlen);
sewardj3b290482011-05-06 21:02:55 +00001225 if (res == 0)
1226 write_ok (own_buf);
1227 else if (res == 1)
1228 /* Unsupported. */
1229 own_buf[0] = '\0';
1230 else
1231 write_enn (own_buf);
1232 }
1233 break;
1234 }
1235 case 'k':
1236 kill_request("Gdb request to kill this process\n");
1237 break;
1238 case 'T': {
1239 unsigned long gdb_id, thread_id;
1240
1241 gdb_id = strtoul (&own_buf[1], NULL, 16);
1242 thread_id = gdb_id_to_thread_id (gdb_id);
1243 if (thread_id == 0) {
1244 write_enn (own_buf);
1245 break;
1246 }
1247
philippe349a3912012-05-23 21:50:36 +00001248 if (valgrind_thread_alive (thread_id))
sewardj3b290482011-05-06 21:02:55 +00001249 write_ok (own_buf);
1250 else
1251 write_enn (own_buf);
1252 break;
1253 }
1254 case 'R':
1255 /* Restarting the inferior is only supported in the
1256 extended protocol.
1257 => It is a request we don't understand. Respond with an
1258 empty packet so that gdb knows that we don't support this
1259 request. */
1260 own_buf[0] = '\0';
1261 break;
1262 case 'v':
1263 /* Extended (long) request. */
sewardj0bb3c672011-07-26 23:29:25 +00001264 handle_v_requests (own_buf, &status, &zignal);
sewardj3b290482011-05-06 21:02:55 +00001265 break;
1266 default:
1267 /* It is a request we don't understand. Respond with an
1268 empty packet so that gdb knows that we don't support this
1269 request. */
1270 own_buf[0] = '\0';
1271 break;
1272 }
1273
1274 if (new_packet_len != -1)
1275 putpkt_binary (own_buf, new_packet_len);
1276 else
1277 putpkt (own_buf);
1278
1279 if (status == 'W')
sewardj0bb3c672011-07-26 23:29:25 +00001280 VG_(umsg) ("\nChild exited with status %d\n", zignal);
sewardj3b290482011-05-06 21:02:55 +00001281 if (status == 'X')
sewardj47ffedb2011-10-24 07:36:57 +00001282 VG_(umsg) ("\nChild terminated with signal = 0x%x (%s)\n",
sewardj0bb3c672011-07-26 23:29:25 +00001283 target_signal_to_host (zignal),
1284 target_signal_to_name (zignal));
sewardj3b290482011-05-06 21:02:55 +00001285 if (status == 'W' || status == 'X') {
1286 VG_(umsg) ("Process exiting\n");
1287 VG_(exit) (0);
1288 }
1289 }
1290
1291 /* We come here when getpkt fails => close the connection,
1292 and re-open. Then return control to valgrind.
1293 We return the control to valgrind as we assume that
1294 the connection was closed due to vgdb having finished
1295 to execute a command. */
1296 if (VG_(clo_verbosity) > 1)
1297 VG_(umsg) ("Remote side has terminated connection. "
1298 "GDBserver will reopen the connection.\n");
1299 remote_finish (reset_after_error);
1300 remote_open (VG_(clo_vgdb_prefix));
1301 myresume (0, 0);
philippe349a3912012-05-23 21:50:36 +00001302 resume_reply_packet_needed = False;
sewardj3b290482011-05-06 21:02:55 +00001303 return;
1304}