1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Main code for remote server for GDB.
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003,
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   2004, 2005, 2006, 2011
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Free Software Foundation, Inc.
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This file is part of GDB.
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   It has been modified to integrate it in valgrind
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is free software; you can redistribute it and/or modify
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   it under the terms of the GNU General Public License as published by
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the Free Software Foundation; either version 2 of the License, or
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (at your option) any later version.
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is distributed in the hope that it will be useful,
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   but WITHOUT ANY WARRANTY; without even the implied warranty of
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   GNU General Public License for more details.
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   You should have received a copy of the GNU General Public License
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   along with this program; if not, write to the Free Software
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Foundation, Inc., 51 Franklin Street, Fifth Floor,
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Boston, MA 02110-1301, USA.  */
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "server.h"
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "regdef.h"
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_options.h"
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_translate.h"
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_mallocfree.h"
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_initimg.h"
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long cont_thread;
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long general_thread;
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long step_thread;
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long thread_from_wait;
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long old_thread_from_wait;
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint pass_signals[TARGET_SIGNAL_LAST]; /* indexed by gdb signal nr */
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* for a gdbserver integrated in valgrind, resuming the process consists
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   in returning the control to valgrind.
41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   The guess process resumes its execution.
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Then at the next error or break or ..., valgrind calls gdbserver again.
43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   A resume reply packet must then be built to inform GDB that the
44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   resume request is finished.
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   resume_reply_packet_needed records the fact that the next call to gdbserver
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   must send a resume packet to gdb. */
47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool resume_reply_packet_needed = False;
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_MINIMAL_JMP_BUF(toplevel);
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Decode a qXfer read request.  Return 0 if everything looks OK,
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   or -1 otherwise.  */
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Extract and NUL-terminate the annex.  */
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *annex = buf;
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (*buf && *buf != ':')
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf++;
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (*buf == '\0')
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = 0;
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* After the read/write marker and annex, qXfer looks like a
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      traditional 'm' packet.  */
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   decode_m_packet (buf, ofs, len);
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Write the response to a successful qXfer read.  Returns the
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   length of the (binary) data stored in BUF, corresponding
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to as much of DATA/LEN as we could fit.  IS_MORE controls
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the first character of the response.  */
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint write_qxfer_response (char *buf, unsigned char *data, int len, int is_more)
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int out_len;
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (is_more)
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf[0] = 'm';
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf[0] = 'l';
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len,
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                PBUFSIZ - POVERHSIZ - 1) + 1;
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool initial_valgrind_sink_saved = False;
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* True <=> valgrind log sink saved in initial_valgrind_sink */
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic OutputSink initial_valgrind_sink;
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool command_output_to_log = False;
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* True <=> command output goes to log instead of gdb */
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid reset_valgrind_sink(char *info)
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(log_output_sink).fd != initial_valgrind_sink.fd
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       && initial_valgrind_sink_saved) {
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(log_output_sink).fd = initial_valgrind_sink.fd;
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg) ("Reset valgrind output to log (%s)\n",
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 (info = NULL ? "" : info));
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid kill_request (char *msg)
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(umsg) ("%s", msg);
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_close();
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(exit) (0);
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* handle_gdb_valgrind_command handles the provided mon string command.
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   If command is recognised, return 1 else return 0.
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Note that in case of ambiguous command, 1 is returned.
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *sink_wanted_at_return is modified if one of the commands
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   'v.set *_output' is handled.
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint handle_gdb_valgrind_command (char* mon, OutputSink* sink_wanted_at_return)
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord ret = 0;
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char s[strlen(mon)+1]; /* copy for strtok_r */
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char* wcmd;
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Char* ssaveptr;
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char* endptr;
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int   kwdid;
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int int_value;
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert (initial_valgrind_sink_saved);
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   strcpy (s, mon);
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   wcmd = strtok_r (s, " ", &ssaveptr);
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* NB: if possible, avoid introducing a new command below which
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      starts with the same 3 first letters as an already existing
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      command. This ensures a shorter abbreviation for the user. */
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (VG_(keyword_id) ("help v.set v.info v.wait v.kill v.translate",
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                            wcmd, kwd_report_duplicated_matches)) {
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case -2:
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case -1:
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  0: /* help */
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      wcmd = strtok_r (NULL, " ", &ssaveptr);
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (wcmd == NULL) {
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int_value = 0;
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         switch (VG_(keyword_id) ("debug", wcmd, kwd_report_all)) {
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         case -2: int_value = 0; break;
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         case -1: int_value = 0; break;
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         case  0: int_value = 1; break;
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         default: tl_assert (0);
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(gdb_printf) (
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"general valgrind monitor commands:\n"
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  help [debug]             : monitor command help. With debug: + debugging commands\n"
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.wait [<ms>]           : sleep <ms> (default 0) then continue\n"
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.info all_errors       : show all errors found so far\n"
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.info last_error       : show last error found\n"
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.info n_errs_found     : show the nr of errors found so far\n"
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.kill                  : kill the Valgrind process\n"
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.set gdb_output        : set valgrind output to gdb\n"
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.set log_output        : set valgrind output to log\n"
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.set mixed_output      : set valgrind output to log, interactive output to gdb\n"
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.set vgdb-error <errornr> : debug me at error >= <errornr> \n");
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (int_value) { VG_(gdb_printf) (
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"debugging valgrind internals monitor commands:\n"
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.info gdbserver_status : show gdbserver status\n"
176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"  v.info memory [aspacemgr] : show valgrind heap memory stats\n"
177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"     (with aspacemgr arg, also shows valgrind segments on log ouput)\n"
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.info scheduler        : show valgrind thread state and stacktrace\n"
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.set debuglog <level>  : set valgrind debug log level to <level>\n"
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"  v.translate <addr> [<traceflags>]  : debug translation of <addr> with <traceflags>\n"
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"    (default traceflags 0b00100000 : show after instrumentation)\n"
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"   An additional flag  0b100000000 allows to show gdbserver instrumentation\n");
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  1: /* v.set */
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      wcmd = strtok_r (NULL, " ", &ssaveptr);
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      switch (kwdid = VG_(keyword_id)
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              ("vgdb-error debuglog gdb_output log_output mixed_output",
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               wcmd, kwd_report_all)) {
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case -2:
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case -1:
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 0: /* vgdb-error */
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 1: /* debuglog */
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         wcmd = strtok_r (NULL, " ", &ssaveptr);
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (wcmd == NULL) {
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            int_value = 0;
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            endptr = "empty"; /* to report an error below */
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            int_value = strtol (wcmd, &endptr, 10);
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (*endptr != '\0') {
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(gdb_printf) ("missing or malformed integer value\n");
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else if (kwdid == 0) {
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(gdb_printf) ("vgdb-error value changed from %d to %d\n",
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                             VG_(dyn_vgdb_error), int_value);
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(dyn_vgdb_error) = int_value;
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else if (kwdid == 1) {
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(gdb_printf) ("debuglog value changed from %d to %d\n",
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                             VG_(debugLog_getLevel)(), int_value);
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(debugLog_startup) (int_value, "gdbsrv");
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            vg_assert (0);
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 2: /* gdb_output */
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (*sink_wanted_at_return).fd = -2;
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         command_output_to_log = False;
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdb_printf) ("valgrind output will go to gdb\n");
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 3: /* log_output */
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (*sink_wanted_at_return).fd = initial_valgrind_sink.fd;
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         command_output_to_log = True;
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdb_printf) ("valgrind output will go to log\n");
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 4: /* mixed output */
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (*sink_wanted_at_return).fd = initial_valgrind_sink.fd;
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         command_output_to_log = False;
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdb_printf)
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ("valgrind output will go to log, interactive output will go to gdb\n");
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      default:
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vg_assert (0);
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  2: /* v.info */ {
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      wcmd = strtok_r (NULL, " ", &ssaveptr);
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      switch (kwdid = VG_(keyword_id)
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              ("all_errors n_errs_found last_error gdbserver_status memory"
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               " scheduler",
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               wcmd, kwd_report_all)) {
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case -2:
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case -1:
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 0: // all_errors
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // A verbosity of minimum 2 is needed to show the errors.
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(show_all_errors)(/* verbosity */ 2, /* xml */ False);
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case  1: // n_errs_found
252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VG_(gdb_printf) ("n_errs_found %d n_errs_shown %d (vgdb-error %d)\n",
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          VG_(get_n_errs_found) (),
254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                          VG_(get_n_errs_shown) (),
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          VG_(dyn_vgdb_error));
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 2: // last_error
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(show_last_error)();
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case  3: // gdbserver_status
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdbserver_status_output)();
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case  4: /* memory */
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(print_all_arena_stats) ();
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (VG_(clo_profile_heap))
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(print_arena_cc_analysis) ();
267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         wcmd = strtok_r (NULL, " ", &ssaveptr);
268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (wcmd != NULL) {
269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            switch (VG_(keyword_id) ("aspacemgr", wcmd, kwd_report_all)) {
270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case -2:
271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case -1: break;
272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case  0:
273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               VG_(am_show_nsegments) (0, "gdbserver v.info memory aspacemgr");
274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               break;
275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            default: tl_assert (0);
276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            }
277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ret = 1;
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case  5: /* scheduler */
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(show_sched_status) ();
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ret = 1;
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      default:
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vg_assert(0);
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  3: /* v.wait */
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      wcmd = strtok_r (NULL, " ", &ssaveptr);
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (wcmd != NULL) {
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int_value = strtol (wcmd, &endptr, 10);
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdb_printf) ("gdbserver: continuing in %d ms ...\n", int_value);
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(poll)(NULL, 0, int_value);
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(gdb_printf) ("gdbserver: continuing after wait ...\n");
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  4: /* v.kill */
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      kill_request ("monitor command request to kill this process\n");
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case  5: { /* v.translate */
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr address;
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      SizeT verbosity = 0x20;
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 1;
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(strtok_get_address_and_size) (&address, &verbosity, &ssaveptr);
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (address != (Addr) 0 || verbosity != 0) {
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* we need to force the output to log for the translation trace,
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            as low level VEX tracing cannot be redirected to gdb. */
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int saved_command_output_to_log = command_output_to_log;
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int saved_fd = VG_(log_output_sink).fd;
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Bool single_stepping_on_entry = valgrind_single_stepping();
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int vex_verbosity = verbosity & 0xff;
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(log_output_sink).fd = initial_valgrind_sink.fd;
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if ((verbosity & 0x100) && !single_stepping_on_entry) {
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            valgrind_set_single_stepping(True);
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            // to force gdbserver instrumentation.
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        if defined(VGA_arm)
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // on arm, we need to (potentially) convert this address
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // to the thumb form.
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         address = thumb_pc (address);
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#        endif
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          address,
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          /*debugging*/True,
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          (Int) vex_verbosity,
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          /*bbs_done*/0,
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          /*allow redir?*/True);
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if ((verbosity & 0x100) && !single_stepping_on_entry) {
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            valgrind_set_single_stepping(False);
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            // reset single stepping.
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         command_output_to_log = saved_command_output_to_log;
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(log_output_sink).fd = saved_fd;
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   default:
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      vg_assert (0);
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return ret;
348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* handle_gdb_monitor_command handles the provided mon string command,
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   which can be either a "standard" valgrind monitor command
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   or a tool specific monitor command.
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   If command recognised, return 1 else return 0.
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Note that in case of ambiguous command, 1 is returned.
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint handle_gdb_monitor_command (char* mon)
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord ret = 0;
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UWord tool_ret = 0;
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // initially, we assume that when returning, the desired sink is the
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // one we have when entering. It can however be changed by the standard
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // valgrind command handling.
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   OutputSink sink_wanted_at_return = VG_(log_output_sink);
365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!initial_valgrind_sink_saved) {
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* first time we enter here, we save the valgrind default log sink */
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      initial_valgrind_sink = sink_wanted_at_return;
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      initial_valgrind_sink_saved = True;
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!command_output_to_log)
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(log_output_sink).fd = -2; /* redirect to monitor_output */
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ret = handle_gdb_valgrind_command (mon, &sink_wanted_at_return);
376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Even if command was recognised by valgrind core, we call the
378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      tool command handler : this is needed to handle help command
379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      and/or to let the tool do some additional processing of a
380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      valgrind standard command. Note however that if valgrind
381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      recognised the command, we will always return success. */
382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(needs).client_requests) {
383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* If the tool reports an error when handling a monitor command,
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         we need to avoid calling gdbserver during this command
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         handling. So, we temporarily set VG_(dyn_vgdb_error) to
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         a huge value to ensure m_errormgr.c does not call gdbserver. */
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int save_dyn_vgdb_error = VG_(dyn_vgdb_error);
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UWord arg[2];
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(dyn_vgdb_error) = 999999999;
390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      arg[0] = (UWord) VG_USERREQ__GDB_MONITOR_COMMAND;
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      arg[1] = (UWord) mon;
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_TDICT_CALL(tool_handle_client_request, VG_(running_tid), arg,
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    &tool_ret);
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(dyn_vgdb_error) = save_dyn_vgdb_error;
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* restore or set the desired output */
398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(log_output_sink).fd = sink_wanted_at_return.fd;
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (ret | tool_ret)
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 1;
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 0;
403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Handle all of the extended 'Q' packets.  */
407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid handle_set (char *arg_own_buf, int *new_packet_len_p)
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strcmp ("QStartNoAckMode", arg_own_buf) == 0) {
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      noack_mode = True;
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_ok (arg_own_buf);
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strncmp ("QPassSignals:", arg_own_buf, 13) == 0) {
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int i;
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char *from, *to;
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char *end = arg_own_buf + strlen(arg_own_buf);
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      CORE_ADDR sig;
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      for (i = 0; i < TARGET_SIGNAL_LAST; i++)
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         pass_signals[i] = 0;
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      from = arg_own_buf + 13;
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      while (from < end) {
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         to = strchr(from, ';');
427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (to == NULL) to = end;
428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         decode_address (&sig, from, to - from);
429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         pass_signals[(int)sig] = 1;
430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         dlog(1, "pass_signal gdb_nr %d %s\n",
431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              (int)sig, target_signal_to_name(sig));
432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         from = to;
433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (*from == ';') from++;
434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_ok (arg_own_buf);
436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Otherwise we didn't know what packet it was.  Say we didn't
439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      understand it.  */
440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   arg_own_buf[0] = 0;
441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Handle all of the extended 'q' packets.  */
444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid handle_query (char *arg_own_buf, int *new_packet_len_p)
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static struct inferior_list_entry *thread_ptr;
448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* qRcmd, monitor command handling.  */
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strncmp ("qRcmd,", arg_own_buf, 6) == 0) {
451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char *p = arg_own_buf + 6;
452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int cmdlen = strlen(p)/2;
453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char cmd[cmdlen+1];
454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (unhexify (cmd, p, cmdlen) != cmdlen) {
456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_enn (arg_own_buf);
457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      cmd[cmdlen] = '\0';
460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (handle_gdb_monitor_command (cmd)) {
462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* In case the command is from a standalone vgdb,
463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            connection will be closed soon => flush the output. */
464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(message_flush) ();
465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_ok (arg_own_buf);
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* cmd not recognised */
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(gdb_printf)
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ("command '%s' not recognised\n"
471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             "In gdb,     try 'monitor help'\n"
472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             "In a shell, try 'vgdb help'\n",
473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             cmd);
474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_ok (arg_own_buf);
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* provide some valgrind specific info in return to qThreadExtraInfo. */
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strncmp ("qThreadExtraInfo,", arg_own_buf, 17) == 0) {
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      unsigned long gdb_id;
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      struct thread_info *ti;
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ThreadState *tst;
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char status[100];
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      gdb_id = strtoul (&arg_own_buf[17], NULL, 16);
487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ti = gdb_id_to_thread (gdb_id);
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (ti != NULL) {
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         tst = (ThreadState *) inferior_target_data (ti);
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Additional info is the tid and the thread status. */
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(snprintf) (status, sizeof(status), "tid %d %s",
492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        tst->tid,
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        VG_(name_of_ThreadStatus)(tst->status));
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         hexify (arg_own_buf, status, strlen(status));
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_enn (arg_own_buf);
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strcmp ("qAttached", arg_own_buf) == 0) {
503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* tell gdb to always detach, never kill the process */
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      arg_own_buf[0] = '1';
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      arg_own_buf[1] = 0;
506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strcmp ("qSymbol::", arg_own_buf) == 0) {
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* We have no symbol to read. */
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_ok (arg_own_buf);
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strcmp ("qfThreadInfo", arg_own_buf) == 0) {
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      thread_ptr = all_threads.head;
517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(sprintf) (arg_own_buf, "m%x",
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    thread_to_gdb_id ((struct thread_info *)thread_ptr));
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      thread_ptr = thread_ptr->next;
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strcmp ("qsThreadInfo", arg_own_buf) == 0) {
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (thread_ptr != NULL) {
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(sprintf) (arg_own_buf, "m%x",
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       thread_to_gdb_id ((struct thread_info *)thread_ptr));
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         thread_ptr = thread_ptr->next;
528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(sprintf) (arg_own_buf, "l");
531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL
536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        && strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      CORE_ADDR ofs;
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      unsigned int len, doc_len;
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char *annex = NULL;
540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // First, the annex is extracted from the packet received.
541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // Then, it is replaced by the corresponding file name.
542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int fd;
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Grab the annex, offset, and length.  */
545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (decode_xfer_read (arg_own_buf + 20, &annex, &ofs, &len) < 0) {
546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         strcpy (arg_own_buf, "E00");
547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (strcmp (annex, "target.xml") == 0) {
551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         annex = valgrind_target_xml(VG_(clo_vgdb_shadow_registers));
552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (annex != NULL && VG_(clo_vgdb_shadow_registers)) {
553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* Ensure the shadow registers are initialized. */
554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            initialize_shadow_low(True);
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (annex == NULL) {
557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            strcpy (arg_own_buf, "E00");
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return;
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      {
563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         char doc[VG_(strlen)(VG_(libdir)) + 1 + VG_(strlen)(annex) + 1];
564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         struct vg_stat stat_doc;
565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char toread[len];
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int len_read;
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(sprintf)(doc, "%s/%s", VG_(libdir), annex);
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         fd = VG_(fd_open) (doc, VKI_O_RDONLY, 0);
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (fd == -1) {
571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            strcpy (arg_own_buf, "E00");
572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return;
573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (VG_(fstat) (fd, &stat_doc) != 0) {
575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(close) (fd);
576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            strcpy (arg_own_buf, "E00");
577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return;
578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         doc_len = stat_doc.size;
580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (len > PBUFSIZ - POVERHSIZ)
582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            len = PBUFSIZ - POVERHSIZ;
583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (ofs > doc_len) {
585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (arg_own_buf);
586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(close) (fd);
587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return;
588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(lseek) (fd, ofs, VKI_SEEK_SET);
590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         len_read = VG_(read) (fd, toread, len);
591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *new_packet_len_p = write_qxfer_response (arg_own_buf, toread,
592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                                   len_read, ofs + len_read < doc_len);
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(close) (fd);
594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strncmp ("qXfer:auxv:read:", arg_own_buf, 16) == 0) {
599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      unsigned char *data;
600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int n;
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      CORE_ADDR ofs;
602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      unsigned int len;
603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      char *annex;
604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Reject any annex; grab the offset and length.  */
606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          || annex[0] != '\0') {
608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         strcpy (arg_own_buf, "E00");
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (len > PBUFSIZ - 2)
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         len = PBUFSIZ - 2;
614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      data = malloc (len);
615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      {
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UWord *client_auxv = VG_(client_auxv);
618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         unsigned int client_auxv_len = 0;
619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         while (*client_auxv != 0) {
620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            dlog(4, "auxv %lld %llx\n",
621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 (ULong)*client_auxv,
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 (ULong)*(client_auxv+1));
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            client_auxv++;
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            client_auxv++;
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            client_auxv_len += 2 * sizeof(UWord);
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         client_auxv_len += 2 * sizeof(UWord);
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(4, "auxv len %d\n", client_auxv_len);
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (ofs >= client_auxv_len)
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            n = -1;
632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else {
633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            n = client_auxv_len - ofs;
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(memcpy) (data, (unsigned char *) VG_(client_auxv), n);
635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (n < 0)
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_enn (arg_own_buf);
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else if (n > len)
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1);
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0);
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      free (data);
646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Protocol features query.  */
652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (strncmp ("qSupported", arg_own_buf, 10) == 0
653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       && (arg_own_buf[10] == ':' || arg_own_buf[10] == '\0')) {
654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(sprintf) (arg_own_buf, "PacketSize=%x", PBUFSIZ - 1);
655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Note: max packet size including frame and checksum, but without
656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         trailing null byte, which is not sent/received. */
657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      strcat (arg_own_buf, ";QStartNoAckMode+");
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      strcat (arg_own_buf, ";QPassSignals+");
660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(client_auxv))
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         strcat (arg_own_buf, ";qXfer:auxv:read+");
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL) {
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         strcat (arg_own_buf, ";qXfer:features:read+");
665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* if a new gdb connects to us, we have to reset the register
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            set to the normal register sets to allow this new gdb to
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            decide to use or not the shadow registers.
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Note that the reset is only done for gdb that are sending
670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            qSupported packets. If a user first connected with a recent
671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            gdb using shadow registers and then with a very old gdb
672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            that does not use qSupported packet, then the old gdb will
673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            not properly connect. */
674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         initialize_shadow_low(False);
675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Otherwise we didn't know what packet it was.  Say we didn't
680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      understand it.  */
681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   arg_own_buf[0] = 0;
682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Handle all of the extended 'v' packets.  */
685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid handle_v_requests (char *arg_own_buf, char *status, int *zignal)
687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* vcont packet code from gdb 6.6 removed */
689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Otherwise we didn't know what packet it was.  Say we didn't
691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      understand it.  */
692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   arg_own_buf[0] = 0;
693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return;
694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid myresume (int step, int sig)
698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct thread_resume resume_info[2];
700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int n = 0;
701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (step || sig) {
703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      resume_info[0].step = step;
704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      resume_info[0].sig = sig;
705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      n++;
706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   resume_info[n].step = 0;
708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   resume_info[n].sig = 0;
709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   resume_reply_packet_needed = True;
711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   valgrind_resume (resume_info);
712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* server_main global variables */
715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic char *own_buf;
716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic unsigned char *mem_buf;
717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid gdbserver_init (void)
719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   dlog(1, "gdbserver_init gdbserver embedded in valgrind: %s\n", version);
721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   noack_mode = False;
722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   valgrind_initialize_target ();
723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // After a fork, gdbserver_init can be called again.
724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // We do not have to re-malloc the buffers in such a case.
725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (own_buf == NULL)
726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      own_buf = malloc (PBUFSIZ);
727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (mem_buf == NULL)
728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      mem_buf = malloc (PBUFSIZ);
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid gdbserver_terminate (void)
732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* last call to gdbserver is cleanup call */
734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_MINIMAL_SETJMP(toplevel)) {
735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(0, "error caused VG_MINIMAL_LONGJMP to gdbserver_terminate\n");
736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_close();
739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid server_main (void)
742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static char status;
744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static int zignal;
745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ch;
747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i = 0;
748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unsigned int len;
749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   CORE_ADDR mem_addr;
750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   zignal = valgrind_wait (&status);
752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_MINIMAL_SETJMP(toplevel)) {
753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(0, "error caused VG_MINIMAL_LONGJMP to server_main\n");
754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (1) {
756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      unsigned char sig;
757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int packet_len;
758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      int new_packet_len = -1;
759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (resume_reply_packet_needed) {
761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Send the resume reply to reply to last GDB resume
762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            request. */
763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         resume_reply_packet_needed = False;
764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         prepare_resume_reply (own_buf, status, zignal);
765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         putpkt (own_buf);
766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      packet_len = getpkt (own_buf);
769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (packet_len <= 0)
770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      i = 0;
773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ch = own_buf[i++];
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      switch (ch) {
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'Q':
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         handle_set (own_buf, &new_packet_len);
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'q':
779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         handle_query (own_buf, &new_packet_len);
780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'd':
782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* set/unset debugging is done through valgrind debug level. */
783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         own_buf[0] = '\0';
784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'D':
786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         reset_valgrind_sink("gdb detaching from process");
787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* When detaching or kill the process, gdb expects to get
789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            an packet OK back.  Any other output will make gdb
790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            believes detach did not work. */
791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_ok (own_buf);
792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         putpkt (own_buf);
793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         remote_finish (reset_after_error);
794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         remote_open (VG_(clo_vgdb_prefix));
795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         myresume (0, 0);
796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         resume_reply_packet_needed = False;
797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case '!':
799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* We can not use the extended protocol with valgrind,
800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            because we can not restart the running
801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            program.  So return unrecognized.  */
802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         own_buf[0] = '\0';
803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case '?':
805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         prepare_resume_reply (own_buf, status, zignal);
806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'H':
808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') {
809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            unsigned long gdb_id, thread_id;
810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            gdb_id = strtoul (&own_buf[2], NULL, 16);
812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            thread_id = gdb_id_to_thread_id (gdb_id);
813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (thread_id == 0) {
814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               write_enn (own_buf);
815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               break;
816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (own_buf[1] == 'g') {
819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               general_thread = thread_id;
820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               set_desired_inferior (1);
821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            } else if (own_buf[1] == 'c') {
822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               cont_thread = thread_id;
823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            } else if (own_buf[1] == 's') {
824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               step_thread = thread_id;
825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_ok (own_buf);
828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            /* Silently ignore it so that gdb can extend the protocol
830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               without compatibility headaches.  */
831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            own_buf[0] = '\0';
832b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
833b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'g':
835b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (1);
836b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         registers_to_string (own_buf);
837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'G':
839b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (1);
840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         registers_from_string (&own_buf[1]);
841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_ok (own_buf);
842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'P': {
844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int regno;
845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char *regbytes;
846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Bool mod;
847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ThreadState *tst;
848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         regno = strtol(&own_buf[1], NULL, 16);
849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         regbytes = strchr(&own_buf[0], '=') + 1;
850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (1);
851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         tst = (ThreadState *) inferior_target_data (current_inferior);
852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Only accept changing registers in "runnable state3.
853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            In fact, it would be ok to change most of the registers
854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            except a few "sensitive" registers such as the PC, SP, BP.
855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            We assume we do not need to very specific here, and that we
856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            can just refuse all of these. */
857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (tst->status == VgTs_Runnable || tst->status == VgTs_Yielding) {
858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            supply_register_from_string (regno, regbytes, &mod);
859b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_ok (own_buf);
860b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
861b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            /* at least from gdb 6.6 onwards, an E. error
862b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               reply is shown to the user. So, we do an error
863b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               msg which both is accepted by gdb as an error msg
864b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               and is readable by the user. */
865b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(sprintf)
866b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               (own_buf,
867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"E.\n"
868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"ERROR changing register %s regno %d\n"
869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"gdb commands changing registers (pc, sp, ...) (e.g. 'jump',\n"
870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"set pc, calling from gdb a function in the debugged process, ...)\n"
871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"can only be accepted if the thread is VgTs_Runnable or VgTs_Yielding state\n"
872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"Thread status is %s\n",
873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                find_register_by_number (regno)->name, regno,
874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                VG_(name_of_ThreadStatus)(tst->status));
875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (VG_(clo_verbosity) > 1)
876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               VG_(umsg) ("%s\n", own_buf);
877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'm':
881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         decode_m_packet (&own_buf[1], &mem_addr, &len);
882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (valgrind_read_memory (mem_addr, mem_buf, len) == 0)
883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            convert_int_to_ascii (mem_buf, own_buf, len);
884b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (own_buf);
886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'M':
888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (valgrind_write_memory (mem_addr, mem_buf, len) == 0)
890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_ok (own_buf);
891b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
892b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (own_buf);
893b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
894b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'X':
895b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (decode_X_packet (&own_buf[1], packet_len - 1,
896b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                              &mem_addr, &len, mem_buf) < 0
897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             || valgrind_write_memory (mem_addr, mem_buf, len) != 0)
898b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (own_buf);
899b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
900b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_ok (own_buf);
901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
902b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'C':
903b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         convert_ascii_to_int (own_buf + 1, &sig, 1);
904b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (target_signal_to_host_p (sig))
905b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            zignal = target_signal_to_host (sig);
906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
907b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            zignal = 0;
908b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (0);
909b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         myresume (0, zignal);
910b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return; // return control to valgrind
911b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'S':
912b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         convert_ascii_to_int (own_buf + 1, &sig, 1);
913b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (target_signal_to_host_p (sig))
914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            zignal = target_signal_to_host (sig);
915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            zignal = 0;
917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (0);
918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         myresume (1, zignal);
919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return; // return control to valgrind
920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'c':
921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (0);
922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         myresume (0, 0);
923b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return; // return control to valgrind
924b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 's':
925b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_desired_inferior (0);
926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         myresume (1, 0);
927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return; // return control to valgrind
928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'Z': {
929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char *lenptr;
930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char *dataptr;
931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int zlen = strtol (lenptr + 1, &dataptr, 16);
933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char type = own_buf[1];
934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (type < '0' || type > '4') {
936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* Watchpoint command type unrecognized. */
937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            own_buf[0] = '\0';
938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
939b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            int res;
940b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            res = valgrind_insert_watchpoint (type, addr, zlen);
942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (res == 0)
943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               write_ok (own_buf);
944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else if (res == 1)
945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               /* Unsupported.  */
946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               own_buf[0] = '\0';
947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else
948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               write_enn (own_buf);
949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
951b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
952b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'z': {
953b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char *lenptr;
954b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char *dataptr;
955b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int zlen = strtol (lenptr + 1, &dataptr, 16);
957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char type = own_buf[1];
958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (type < '0' || type > '4') {
960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* Watchpoint command type unrecognized. */
961b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            own_buf[0] = '\0';
962b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            int res;
964b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            res = valgrind_remove_watchpoint (type, addr, zlen);
966b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (res == 0)
967b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               write_ok (own_buf);
968b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else if (res == 1)
969b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               /* Unsupported.  */
970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               own_buf[0] = '\0';
971b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else
972b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               write_enn (own_buf);
973b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
975b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
976b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'k':
977b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         kill_request("Gdb request to kill this process\n");
978b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
979b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'T': {
980b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         unsigned long gdb_id, thread_id;
981b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
982b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         gdb_id = strtoul (&own_buf[1], NULL, 16);
983b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         thread_id = gdb_id_to_thread_id (gdb_id);
984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (thread_id == 0) {
985b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (own_buf);
986b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            break;
987b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
988b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (valgrind_thread_alive (thread_id))
990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_ok (own_buf);
991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
992b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            write_enn (own_buf);
993b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
994b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
995b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'R':
996b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Restarting the inferior is only supported in the
997b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            extended protocol.
998b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            => It is a request we don't understand.  Respond with an
999b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            empty packet so that gdb knows that we don't support this
1000b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            request.  */
1001b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         own_buf[0] = '\0';
1002b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
1003b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case 'v':
1004b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Extended (long) request.  */
1005b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         handle_v_requests (own_buf, &status, &zignal);
1006b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
1007b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      default:
1008b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* It is a request we don't understand.  Respond with an
1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            empty packet so that gdb knows that we don't support this
1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            request.  */
1011b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         own_buf[0] = '\0';
1012b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
1013b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
1014b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1015b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (new_packet_len != -1)
1016b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         putpkt_binary (own_buf, new_packet_len);
1017b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else
1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         putpkt (own_buf);
1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1020b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (status == 'W')
1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(umsg) ("\nChild exited with status %d\n", zignal);
1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (status == 'X')
1023b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(umsg) ("\nChild terminated with signal = 0x%x (%s)\n",
1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    target_signal_to_host (zignal),
1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    target_signal_to_name (zignal));
1026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (status == 'W' || status == 'X') {
1027b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(umsg) ("Process exiting\n");
1028b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(exit) (0);
1029b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1031b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1032b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* We come here when getpkt fails => close the connection,
1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      and re-open. Then return control to valgrind.
1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      We return the control to valgrind as we assume that
1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      the connection was closed due to vgdb having finished
1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      to execute a command. */
1037b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(clo_verbosity) > 1)
1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg) ("Remote side has terminated connection.  "
1039b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 "GDBserver will reopen the connection.\n");
1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_finish (reset_after_error);
1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_open (VG_(clo_vgdb_prefix));
1042b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   myresume (0, 0);
1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   resume_reply_packet_needed = False;
1044b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return;
1045b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1046