1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Remote utility routines for the remote server for GDB.
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   2001, 2002, 2003, 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 "pub_core_basics.h"
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_vki.h"
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_vkiscnums.h"
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsignal.h"
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_options.h"
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "server.h"
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  if defined(VGO_linux)
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/prctl.h>
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  endif
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovBool noack_mode;
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int readchar (int single);
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid remote_utils_output_status(void);
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int remote_desc;
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic VgdbShared *shared;
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int  last_looked_cntr = -1;
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic struct vki_pollfd remote_desc_pollfdread_activity;
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define INVALID_DESCRIPTOR -1
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* for a gdbserver embedded in valgrind, we read from a FIFO and write
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to another FIFO So, we need two descriptors */
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int write_remote_desc = INVALID_DESCRIPTOR;
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int pid_from_to_creator;
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* only this pid will remove the FIFOs: if an exec fails, we must avoid
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   that the exiting child believes it has to remove the FIFOs of its parent */
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic int mknod_done = 0;
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic char *from_gdb = NULL;
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic char *to_gdb = NULL;
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic char *shared_mem = NULL;
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint open_fifo (char *side, char *path, int flags)
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  SysRes o;
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  int fd;
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  dlog(1, "Opening %s side %s\n", side, path);
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  o = VG_(open) (path, flags, 0);
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (sr_isError (o)) {
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     sr_perror(o, "open fifo %s\n", path);
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     fatal ("valgrind: fatal error: vgdb FIFO cannot be opened.\n");
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  } else {
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     fd = sr_Res(o);
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     dlog(1, "result fd %d\n", fd);
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  }
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  fd = VG_(safe_fd)(fd);
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  dlog(1, "result safe_fd %d\n", fd);
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (fd == -1)
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     fatal("safe_fd for vgdb FIFO failed\n");
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return fd;
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid remote_utils_output_status(void)
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (shared == NULL)
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("remote communication not initialized\n");
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("shared->written_by_vgdb %d shared->seen_by_valgrind %d\n",
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                shared->written_by_vgdb, shared->seen_by_valgrind);
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Returns 0 if vgdb and connection state looks good,
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   otherwise returns an int value telling which check failed. */
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint vgdb_state_looks_bad(char* where)
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(kill)(shared->vgdb_pid, 0) != 0)
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 1; // vgdb process does not exist anymore.
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_desc_activity(where) == 2)
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 2; // check for error on remote desc shows a problem
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_desc == INVALID_DESCRIPTOR)
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 3; // after check, remote_desc not ok anymore
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0; // all is ok.
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* On systems that defines PR_SET_PTRACER, verify if ptrace_scope is
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   is permissive enough for vgdb. Otherwise, call set_ptracer.
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This is especially aimed at Ubuntu >= 10.10 which has added
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the ptrace_scope context. */
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid set_ptracer(void)
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef PR_SET_PTRACER
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SysRes o;
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int fd;
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ptrace_scope;
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int ret;
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   o = VG_(open) (ptrace_scope_setting_file, VKI_O_RDONLY, 0);
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (sr_isError(o)) {
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(debugLog_getLevel)() >= 1) {
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         sr_perror(o, "error VG_(open) %s\n", ptrace_scope_setting_file);
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* can't read setting. Assuming ptrace can be called by vgdb. */
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   fd = sr_Res(o);
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(read) (fd, &ptrace_scope, 1) == 1) {
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "ptrace_scope %c\n", ptrace_scope);
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (ptrace_scope != '0') {
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* insufficient default ptrace_scope.
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Indicate to the kernel that we accept to be
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ptraced by our vgdb. */
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ret = VG_(prctl) (PR_SET_PTRACER, shared->vgdb_pid, 0, 0, 0);
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "set_ptracer to vgdb_pid %d result %d\n",
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              shared->vgdb_pid, ret);
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } else {
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(0, "Could not read the ptrace_scope setting from %s\n",
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           ptrace_scope_setting_file);
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(close) (fd);
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* returns 1 if one or more poll "errors" is set.
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Errors are: VKI_POLLERR or VKI_POLLHUP or VKI_POLLNAL */
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint poll_cond (short revents)
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return (revents & (VKI_POLLERR | VKI_POLLHUP | VKI_POLLNVAL));
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Ensures we have a valid write file descriptor.
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Returns 1 if we have a valid write file descriptor,
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   0 if the write fd could not be opened. */
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint ensure_write_remote_desc(void)
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vki_pollfd write_remote_desc_ok;
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int ret;
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (write_remote_desc != INVALID_DESCRIPTOR) {
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_remote_desc_ok.fd = write_remote_desc;
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_remote_desc_ok.events = VKI_POLLOUT;
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      write_remote_desc_ok.revents = 0;
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = VG_(poll)(&write_remote_desc_ok, 1, 0);
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (ret && poll_cond(write_remote_desc_ok.revents)) {
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "POLLcond %d closing write_remote_desc %d\n",
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              write_remote_desc_ok.revents, write_remote_desc);
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(close) (write_remote_desc);
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_remote_desc = INVALID_DESCRIPTOR;
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (write_remote_desc == INVALID_DESCRIPTOR) {
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* open_fifo write will block if the receiving vgdb
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         process is dead.  So, let's check for vgdb state to
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         be reasonably sure someone is reading on the other
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         side of the fifo. */
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (!vgdb_state_looks_bad("bad?@ensure_write_remote_desc")) {
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         set_ptracer();
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         write_remote_desc = open_fifo ("write", to_gdb, VKI_O_WRONLY);
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return (write_remote_desc != INVALID_DESCRIPTOR);
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_darwin)
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VKI_S_IFIFO 0010000
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid safe_mknod (char *nod)
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SysRes m;
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   m = VG_(mknod) (nod, VKI_S_IFIFO|0666, 0);
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (sr_isError (m)) {
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (sr_Err (m) == VKI_EEXIST) {
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (VG_(clo_verbosity) > 1) {
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(umsg)("%s already created\n", nod);
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         sr_perror(m, "mknod %s\n", nod);
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(umsg) ("valgrind: fatal error: vgdb FIFOs cannot be created.\n");
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(exit)(1);
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Open a connection to a remote debugger.
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   NAME is the filename used for communication.
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   For Valgrind, name is the prefix for the two read and write FIFOs
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The two FIFOs names will be build by appending
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   -from-vgdb-to-pid-by-user-on-host and -to-vgdb-from-pid-by-user-on-host
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   with pid being the pidnr of the valgrind process These two FIFOs
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   will be created if not existing yet. They will be removed when
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the gdbserver connection is closed or the process exits */
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid remote_open (char *name)
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const HChar *user, *host;
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int save_fcntl_flags, len;
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VgdbShared vgdbinit =
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      {0, 0, 0, (Addr) VG_(invoke_gdbserver),
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       (Addr) VG_(threads), sizeof(ThreadState),
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       offsetof(ThreadState, status),
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       offsetof(ThreadState, os_state) + offsetof(ThreadOSstate, lwpid)};
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const int pid = VG_(getpid)();
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const int name_default = strcmp(name, VG_(vgdb_prefix_default)()) == 0;
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr addr_shared;
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SysRes o;
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int shared_mem_fd = INVALID_DESCRIPTOR;
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   user = VG_(getenv)("LOGNAME");
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (user == NULL) user = VG_(getenv)("USER");
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (user == NULL) user = "???";
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   host = VG_(getenv)("HOST");
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (host == NULL) host = VG_(getenv)("HOSTNAME");
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (host == NULL) host = "???";
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   len = strlen(name) + strlen(user) + strlen(host) + 40;
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (from_gdb != NULL)
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      free (from_gdb);
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   from_gdb = malloc (len);
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (to_gdb != NULL)
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      free (to_gdb);
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to_gdb = malloc (len);
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (shared_mem != NULL)
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      free (shared_mem);
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   shared_mem = malloc (len);
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* below 3 lines must match the equivalent in vgdb.c */
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(sprintf) (from_gdb,   "%s-from-vgdb-to-%d-by-%s-on-%s",    name,
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 pid, user, host);
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(sprintf) (to_gdb,     "%s-to-vgdb-from-%d-by-%s-on-%s",    name,
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 pid, user, host);
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(sprintf) (shared_mem, "%s-shared-mem-vgdb-%d-by-%s-on-%s", name,
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 pid, user, host);
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(clo_verbosity) > 1) {
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("embedded gdbserver: reading from %s\n", from_gdb);
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("embedded gdbserver: writing to   %s\n", to_gdb);
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("embedded gdbserver: shared mem   %s\n", shared_mem);
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("\n");
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("TO CONTROL THIS PROCESS USING vgdb (which you probably\n"
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                "don't want to do, unless you know exactly what you're doing,\n"
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                "or are doing some strange experiment):\n"
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                "  %s/../../bin/vgdb --pid=%d%s%s ...command...\n",
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                VG_LIBDIR,
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                pid, (name_default ? "" : " --vgdb-prefix="),
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                (name_default ? "" : name));
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(clo_verbosity) > 1
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       || VG_(clo_vgdb_error) < 999999999) {
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("\n");
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)(
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "TO DEBUG THIS PROCESS USING GDB: start GDB like this\n"
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "  /path/to/gdb %s\n"
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "and then give GDB the following command\n"
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "  target remote | %s/../../bin/vgdb --pid=%d%s%s\n",
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(args_the_exename),
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_LIBDIR,
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         pid, (name_default ? "" : " --vgdb-prefix="),
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (name_default ? "" : name)
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("--pid is optional if only one valgrind process is running\n");
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)("\n");
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!mknod_done) {
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mknod_done++;
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /*
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       * Unlink just in case a previous process with the same PID had been
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       * killed and hence Valgrind hasn't had the chance yet to remove these.
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       */
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(unlink)(from_gdb);
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(unlink)(to_gdb);
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(unlink)(shared_mem);
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      safe_mknod(from_gdb);
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      safe_mknod(to_gdb);
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      pid_from_to_creator = pid;
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      o = VG_(open) (shared_mem, VKI_O_CREAT|VKI_O_RDWR, 0666);
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (sr_isError (o)) {
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         sr_perror(o, "cannot create shared_mem file %s\n", shared_mem);
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         fatal("");
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         shared_mem_fd = sr_Res(o);
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(write)(shared_mem_fd, &vgdbinit, sizeof(VgdbShared))
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          != sizeof(VgdbShared)) {
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         fatal("error writing %d bytes to shared mem %s\n",
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               (int) sizeof(VgdbShared), shared_mem);
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      {
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         SysRes res = VG_(am_shared_mmap_file_float_valgrind)
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            (sizeof(VgdbShared), VKI_PROT_READ|VKI_PROT_WRITE,
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             shared_mem_fd, (Off64T)0);
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (sr_isError(res)) {
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            sr_perror(res, "error VG_(am_shared_mmap_file_float_valgrind) %s\n",
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                      shared_mem);
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            fatal("");
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addr_shared = sr_Res (res);
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      shared = (VgdbShared*) addr_shared;
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(close) (shared_mem_fd);
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* we open the read side FIFO in non blocking mode
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      We then set the fd in blocking mode.
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Opening in non-blocking read mode always succeeds while opening
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      in non-blocking write mode succeeds only if the fifo is already
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      opened in read mode. So, we wait till we have read the first
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      character from the read side before opening the write side. */
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc = open_fifo ("read", from_gdb, VKI_O_RDONLY|VKI_O_NONBLOCK);
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   save_fcntl_flags = VG_(fcntl) (remote_desc, VKI_F_GETFL, 0);
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(fcntl) (remote_desc, VKI_F_SETFL, save_fcntl_flags & ~VKI_O_NONBLOCK);
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc_pollfdread_activity.fd = remote_desc;
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc_pollfdread_activity.events = VKI_POLLIN;
348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc_pollfdread_activity.revents = 0;
349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* sync_gdb_connection wait a time long enough to let the connection
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   be properly closed if needed when closing the connection (in case
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   of detach or error), if we reopen it too quickly, it seems there
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   are some events queued in the kernel concerning the "old"
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   connection/remote_desc which are discovered with poll or select on
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the "new" connection/remote_desc.  We bypass this by waiting some
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   time to let a proper cleanup to be donex */
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid sync_gdb_connection(void)
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(poll)(0, 0, 100);
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovchar * ppFinishReason (FinishReason reason)
365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (reason) {
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case orderly_finish:    return "orderly_finish";
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case reset_after_error: return "reset_after_error";
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case reset_after_fork:  return "reset_after_fork";
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   default: vg_assert (0);
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid remote_finish (FinishReason reason)
375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   dlog(1, "remote_finish (reason %s) %d %d\n",
377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ppFinishReason(reason), remote_desc, write_remote_desc);
378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   reset_valgrind_sink(ppFinishReason(reason));
379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (write_remote_desc != INVALID_DESCRIPTOR)
380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(close) (write_remote_desc);
381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   write_remote_desc = INVALID_DESCRIPTOR;
382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_desc != INVALID_DESCRIPTOR) {
383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      remote_desc_pollfdread_activity.fd = INVALID_DESCRIPTOR;
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      remote_desc_pollfdread_activity.events = 0;
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      remote_desc_pollfdread_activity.revents = 0;
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(close) (remote_desc);
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc = INVALID_DESCRIPTOR;
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   noack_mode = False;
390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* ensure the child will create its own FIFOs */
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (reason == reset_after_fork)
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mknod_done = 0;
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (reason == reset_after_error)
396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sync_gdb_connection();
397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* orderly close, cleans up everything */
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid remote_close (void)
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const int pid = VG_(getpid)();
403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_finish(orderly_finish);
404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (pid == pid_from_to_creator) {
405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "unlinking\n    %s\n    %s\n    %s\n",
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           from_gdb, to_gdb, shared_mem);
407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(unlink) (from_gdb) == -1)
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         warning ("could not unlink %s\n", from_gdb);
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(unlink) (to_gdb) == -1)
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         warning ("could not unlink %s\n", to_gdb);
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(unlink) (shared_mem) == -1)
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         warning ("could not unlink %s\n", shared_mem);
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else {
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "not creator => not unlinking %s and %s\n", from_gdb, to_gdb);
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   free (from_gdb);
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   free (to_gdb);
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovBool remote_connected(void)
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return write_remote_desc != INVALID_DESCRIPTOR;
424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* cleanup after an error detected by poll_cond */
427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid error_poll_cond(void)
429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* if we will close the connection, we assume either that
431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      all characters have been seen or that they will be dropped. */
432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   shared->seen_by_valgrind = shared->written_by_vgdb;
433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_finish(reset_after_error);
434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* remote_desc_activity might be used at high frequency if the user
437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   gives a small value to --vgdb-poll. So, the function avoids
438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   doing repetitively system calls by rather looking at the
439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   counter values maintained in shared memory by vgdb. */
440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint remote_desc_activity(char *msg)
441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int ret;
443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const int looking_at = shared->written_by_vgdb;
444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (shared->seen_by_valgrind == looking_at)
445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   //   if (last_looked_cntr == looking_at)
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 0;
447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_desc == INVALID_DESCRIPTOR)
448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 0;
449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* poll the remote desc */
451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc_pollfdread_activity.revents = 0;
452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ret = VG_(poll) (&remote_desc_pollfdread_activity, 1, 0);
453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (ret && poll_cond(remote_desc_pollfdread_activity.revents)) {
454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "POLLcond %d remote_desc_pollfdread %d\n",
455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           remote_desc_pollfdread_activity.revents, remote_desc);
456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      error_poll_cond();
457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ret = 2;
458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   dlog(1,
460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        "remote_desc_activity %s %d last_looked_cntr %d looking_at %d"
461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        " shared->written_by_vgdb %d shared->seen_by_valgrind %d"
462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        " ret %d\n",
463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        msg, remote_desc, last_looked_cntr, looking_at,
464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        shared->written_by_vgdb, shared->seen_by_valgrind,
465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        ret);
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* if no error from poll, indicate we have "seen" up to looking_at */
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (ret != 2)
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      last_looked_cntr = looking_at;
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return ret;
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Convert hex digit A to a number.  */
473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint fromhex (int a)
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (a >= '0' && a <= '9')
478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return a - '0';
479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else if (a >= 'a' && a <= 'f')
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return a - 'a' + 10;
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      error ("Reply contains invalid hex digit 0x%x\n", a);
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint unhexify (char *bin, const char *hex, int count)
487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i;
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < count; i++) {
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (hex[0] == 0 || hex[1] == 0) {
492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Hex string is short, or of uneven length.
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Return the count that has been converted so far. */
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return i;
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      hex += 2;
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return i;
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid decode_address (CORE_ADDR *addrp, const char *start, int len)
503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   CORE_ADDR addr;
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ch;
506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i;
507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   addr = 0;
509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < len; i++) {
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ch = start[i];
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr = addr << 4;
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addr = addr | (fromhex (ch) & 0x0f);
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *addrp = addr;
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Convert number NIB to a hex digit.  */
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint tohex (int nib)
521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (nib < 10)
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return '0' + nib;
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 'a' + nib - 10;
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint hexify (char *hex, const char *bin, int count)
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i;
531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* May use a length, or a nul-terminated string as input. */
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (count == 0)
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      count = strlen (bin);
535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  for (i = 0; i < count; i++) {
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     *hex++ = tohex ((*bin >> 4) & 0xf);
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     *hex++ = tohex (*bin++ & 0xf);
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  }
540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  *hex = 0;
541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return i;
542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Convert BUFFER, binary data at least LEN bytes long, into escaped
545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   binary data in OUT_BUF.  Set *OUT_LEN to the length of the data
546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   encoded in OUT_BUF, and return the number of bytes in OUT_BUF
547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (which may be more than *OUT_LEN due to escape characters).  The
548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   total number of bytes in the output buffer will be at most
549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   OUT_MAXLEN.  */
550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint
552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovremote_escape_output (const gdb_byte *buffer, int len,
553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		      gdb_byte *out_buf, int *out_len,
554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		      int out_maxlen)
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int input_index, output_index;
557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   output_index = 0;
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (input_index = 0; input_index < len; input_index++) {
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      gdb_byte b = buffer[input_index];
561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (b == '$' || b == '#' || b == '}' || b == '*') {
563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* These must be escaped.  */
564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (output_index + 2 > out_maxlen)
565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    break;
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         out_buf[output_index++] = '}';
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         out_buf[output_index++] = b ^ 0x20;
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (output_index + 1 > out_maxlen)
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    break;
571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         out_buf[output_index++] = b;
572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *out_len = input_index;
576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return output_index;
577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Convert BUFFER, escaped data LEN bytes long, into binary data
580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   in OUT_BUF.  Return the number of bytes written to OUT_BUF.
581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Raise an error if the total number of bytes exceeds OUT_MAXLEN.
582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This function reverses remote_escape_output.  It allows more
584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   escaped characters than that function does, in particular because
585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   '*' must be escaped to avoid the run-length encoding processing
586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   in reading packets.  */
587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint remote_unescape_input (const gdb_byte *buffer, int len,
590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		       gdb_byte *out_buf, int out_maxlen)
591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int input_index, output_index;
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int escaped;
594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   output_index = 0;
596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   escaped = 0;
597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (input_index = 0; input_index < len; input_index++) {
598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      gdb_byte b = buffer[input_index];
599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (output_index + 1 > out_maxlen)
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         error ("Received too much data (len %d) from the target.\n", len);
602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (escaped) {
604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         out_buf[output_index++] = b ^ 0x20;
605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         escaped = 0;
606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else if (b == '}') {
607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         escaped = 1;
608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         out_buf[output_index++] = b;
610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (escaped)
614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      error ("Unmatched escape character in target response.\n");
615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return output_index;
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Look for a sequence of characters which can be run-length encoded.
620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   If there are any, update *CSUM and *P.  Otherwise, output the
621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   single character.  Return the number of characters consumed.  */
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint try_rle (char *buf, int remaining, unsigned char *csum, char **p)
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int n;
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Always output the character.  */
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *csum += buf[0];
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *(*p)++ = buf[0];
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Don't go past '~'.  */
633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remaining > 97)
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      remaining = 97;
635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (n = 1; n < remaining; n++)
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (buf[n] != buf[0])
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* N is the index of the first character not the same as buf[0].
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      buf[0] is counted twice, so by decrementing N, we get the number
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      of characters the RLE sequence will replace.  */
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   n--;
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (n < 3)
646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return 1;
647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Skip the frame characters.  The manual says to skip '+' and '-'
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      also, but there's no reason to.  Unfortunately these two unusable
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      characters double the encoded length of a four byte zero
651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      value.  */
652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (n + 29 == '$' || n + 29 == '#')
653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      n--;
654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *csum += '*';
656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *(*p)++ = '*';
657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *csum += n + 29;
658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *(*p)++ = n + 29;
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return n + 1;
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Send a packet to the remote machine, with error checking.
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The data of the packet is in BUF, and the length of the
665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   packet is in CNT.  Returns >= 0 on success, -1 otherwise.  */
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint putpkt_binary (char *buf, int cnt)
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i;
670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unsigned char csum = 0;
671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char *buf2;
672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char *p;
673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int cc;
674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf2 = malloc (PBUFSIZ);
676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Copy the packet into buffer BUF2, encapsulating it
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      and giving it a checksum.  */
679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = buf2;
681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *p++ = '$';
682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < cnt;)
684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      i += try_rle (buf + i, cnt - i, &csum, &p);
685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *p++ = '#';
687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *p++ = tohex ((csum >> 4) & 0xf);
688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *p++ = tohex (csum & 0xf);
689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *p = '\0';
691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* we might have to write a pkt when out FIFO not yet/anymore opened */
693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!ensure_write_remote_desc()) {
694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      warning ("putpkt(write) error: no write_remote_desc\n");
695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Send it once (noack_mode)
699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      or send it over and over until we get a positive ack.  */
700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {
702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(write) (write_remote_desc, buf2, p - buf2) != p - buf2) {
703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         warning ("putpkt(write) error\n");
704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return -1;
705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (noack_mode)
708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "putpkt (\"%s\"); [no ack]\n", buf2);
709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else
710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1,"putpkt (\"%s\"); [looking for ack]\n", buf2);
711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (noack_mode)
713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      cc = readchar (1);
716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (cc > 0)
717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "[received '%c' (0x%x)]\n", cc, cc);
718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (cc <= 0) {
720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (cc == 0)
721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            dlog(1, "putpkt(read): Got EOF\n");
722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    warning ("putpkt(read) error\n");
724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         free (buf2);
726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return -1;
727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Check for an input interrupt while we're here.  */
730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (cc == '\003')
731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (*the_target->send_signal) (VKI_SIGINT);
732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (cc != '+');
734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   free (buf2);
736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 1;			/* Success! */
737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Send a packet to the remote machine, with error checking.  The data
740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   of the packet is in BUF, and the packet should be a NUL-terminated
741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   string.  Returns >= 0 on success, -1 otherwise.  */
742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint putpkt (char *buf)
744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return putpkt_binary (buf, strlen (buf));
746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid monitor_output (char *s)
749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const int len = strlen(s);
751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char *buf = malloc(1 + 2*len + 1);
752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[0] = 'O';
754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   hexify(buf+1, s, len);
755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (putpkt (buf) < 0) {
756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* We probably have lost the connection with vgdb. */
757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      reset_valgrind_sink("Error writing monitor output");
758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* write again after reset */
759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(printf) ("%s", s);
760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   free (buf);
763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Returns next char from remote GDB.  -1 if error.  */
766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* if single, only one character maximum can be read with
767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   read system call. Otherwise, when reading an ack character
768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   we might pile up the next gdb command in the static buf.
769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The read loop is then blocked in poll till gdb times out. */
770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint readchar (int single)
772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static unsigned char buf[PBUFSIZ];
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static int bufcnt = 0;
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   static unsigned char *bufp;
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int ret;
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (bufcnt-- > 0)
779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return *bufp++;
780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_desc == INVALID_DESCRIPTOR)
782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* No characters available in buf =>
785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      wait for some characters to arrive */
786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   remote_desc_pollfdread_activity.revents = 0;
787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ret = VG_(poll)(&remote_desc_pollfdread_activity, 1, -1);
788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (ret != 1) {
789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(0, "readchar: poll got %d\n", ret);
790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (single)
793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      bufcnt = VG_(read) (remote_desc, buf, 1);
794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      bufcnt = VG_(read) (remote_desc, buf, sizeof (buf));
796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (bufcnt <= 0) {
798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (bufcnt == 0)
799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog (1, "readchar: Got EOF\n");
800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else
801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         warning ("readchar read error\n");
802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   shared->seen_by_valgrind += bufcnt;
807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* If we have received a character and we do not yet have a
809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      connection, we better open our "write" fifo to let vgdb open its
810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      read fifo side */
811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (write_remote_desc == INVALID_DESCRIPTOR
812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       && !ensure_write_remote_desc()) {
813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "reachar: write_remote_desc could not be created");
814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   bufp = buf;
817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   bufcnt--;
818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (poll_cond(remote_desc_pollfdread_activity.revents)) {
820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "readchar: POLLcond got %d\n",
821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           remote_desc_pollfdread_activity.revents);
822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      error_poll_cond();
823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return *bufp++;
826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Read a packet from the remote machine, with error checking,
830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   and store it in BUF.  Returns length of packet, or negative if error. */
831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
832b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint getpkt (char *buf)
833b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char *bp;
835b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unsigned char csum, c1, c2;
836b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int c;
837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (1) {
839b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      csum = 0;
840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      while (1) {
842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         c = readchar (0);
843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (c == '$')
844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    break;
845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "[getpkt: discarding char '%c']\n", c);
846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (c < 0)
847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    return -1;
848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      bp = buf;
851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      while (1) {
852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         c = readchar (0);
853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (c < 0)
854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    return -1;
855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (c == '#')
856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	    break;
857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *bp++ = c;
858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         csum += c;
859b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
860b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *bp = 0;
861b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
862b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      c1 = fromhex (readchar (0));
863b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      c2 = fromhex (readchar (0));
864b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
865b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (csum == (c1 << 4) + c2)
866b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog (0, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            (c1 << 4) + c2, csum, buf);
870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (!ensure_write_remote_desc()) {
871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "getpkt(write nack) no write_remote_desc");
872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(write) (write_remote_desc, "-", 1);
874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (noack_mode)
877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "getpkt (\"%s\");  [no ack] \n", buf);
878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "getpkt (\"%s\");  [sending ack] \n", buf);
880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!noack_mode) {
882b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (!ensure_write_remote_desc()) {
883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "getpkt(write ack) no write_remote_desc");
884b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(write) (write_remote_desc, "+", 1);
886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "[sent ack]\n");
887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return bp - buf;
890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
891b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
892b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid write_ok (char *buf)
893b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
894b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[0] = 'O';
895b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[1] = 'K';
896b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[2] = '\0';
897b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
898b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
899b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid write_enn (char *buf)
900b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Some day, we should define the meanings of the error codes... */
902b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[0] = 'E';
903b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[1] = '0';
904b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[2] = '1';
905b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf[3] = '\0';
906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
907b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
908b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid convert_int_to_ascii (unsigned char *from, char *to, int n)
909b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
910b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int nib;
911b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int ch;
912b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (n--) {
913b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ch = *from++;
914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      nib = ((ch & 0xf0) >> 4) & 0x0f;
915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *to++ = tohex (nib);
916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      nib = ch & 0x0f;
917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *to++ = tohex (nib);
918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *to++ = 0;
920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
923b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid convert_ascii_to_int (char *from, unsigned char *to, int n)
924b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
925b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int nib1, nib2;
926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (n--) {
927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      nib1 = fromhex (*from++);
928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      nib2 = fromhex (*from++);
929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovchar * outreg (int regno, char *buf)
935b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if ((regno >> 12) != 0)
937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *buf++ = tohex ((regno >> 12) & 0xf);
938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if ((regno >> 8) != 0)
939b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *buf++ = tohex ((regno >> 8) & 0xf);
940b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = tohex ((regno >> 4) & 0xf);
941b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = tohex (regno & 0xf);
942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = ':';
943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   collect_register_as_string (regno, buf);
944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   buf += 2 * register_size (regno);
945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = ';';
946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return buf;
948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid prepare_resume_reply (char *buf, char status, unsigned char sig)
951b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
952b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int nib;
953b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
954b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = status;
955b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   nib = ((sig & 0xf0) >> 4);
957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = tohex (nib);
958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   nib = sig & 0x0f;
959b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = tohex (nib);
960b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
961b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (status == 'T') {
962b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      const char **regp = gdbserver_expedite_regs;
963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
964b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (the_target->stopped_by_watchpoint != NULL
965b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	  && (*the_target->stopped_by_watchpoint) ()) {
966b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         CORE_ADDR addr;
967b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         int i;
968b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
969b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         strncpy (buf, "watch:", 6);
970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         buf += 6;
971b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
972b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addr = (*the_target->stopped_data_address) ();
973b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Convert each byte of the address into two hexadecimal chars.
975b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            Note that we take sizeof (void *) instead of sizeof (addr);
976b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            this is to avoid sending a 64-bit address to a 32-bit GDB.  */
977b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         for (i = sizeof (void *) * 2; i > 0; i--) {
978b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
979b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
980b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *buf++ = ';';
981b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
982b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
983b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      while (*regp) {
984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         buf = outreg (find_regno (*regp), buf);
985b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         regp ++;
986b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
987b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
988b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      {
989b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         unsigned int gdb_id_from_wait;
990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* FIXME right place to set this? */
992b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         thread_from_wait =
993b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((struct inferior_list_entry *)current_inferior)->id;
994b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         gdb_id_from_wait = thread_to_gdb_id (current_inferior);
995b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
996b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(1, "Writing resume reply for %ld\n", thread_from_wait);
997b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* This if (1) ought to be unnecessary.  But remote_wait in GDB
998b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            will claim this event belongs to inferior_ptid if we do not
999b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            specify a thread, and there's no way for gdbserver to know
1000b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            what inferior_ptid is.  */
1001b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (1 || old_thread_from_wait != thread_from_wait) {
1002b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            general_thread = thread_from_wait;
1003b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(sprintf) (buf, "thread:%x;", gdb_id_from_wait);
1004b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            buf += strlen (buf);
1005b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            old_thread_from_wait = thread_from_wait;
1006b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
1007b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
1008b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* For W and X, we're done.  */
1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *buf++ = 0;
1011b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1012b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1013b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
1014b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1015b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i = 0, j = 0;
1016b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ch;
1017b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *mem_addr_ptr = *len_ptr = 0;
1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((ch = from[i++]) != ',') {
1020b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr = *mem_addr_ptr << 4;
1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr |= fromhex (ch) & 0x0f;
1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1023b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (j = 0; j < 4; j++) {
1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if ((ch = from[i++]) == 0)
1026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
1027b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr = *len_ptr << 4;
1028b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr |= fromhex (ch) & 0x0f;
1029b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1031b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1032b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		 unsigned char *to)
1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i = 0;
1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ch;
1037b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *mem_addr_ptr = *len_ptr = 0;
1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1039b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((ch = from[i++]) != ',') {
1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr = *mem_addr_ptr << 4;
1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr |= fromhex (ch) & 0x0f;
1042b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1043b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1044b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((ch = from[i++]) != ':') {
1045b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr = *len_ptr << 4;
1046b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr |= fromhex (ch) & 0x0f;
1047b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1048b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1049b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   convert_ascii_to_int (&from[i++], to, *len_ptr);
1050b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1051b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1052b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
1053b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		 unsigned int *len_ptr, unsigned char *to)
1054b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1055b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int i = 0;
1056b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   char ch;
1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *mem_addr_ptr = *len_ptr = 0;
1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1059b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((ch = from[i++]) != ',') {
1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr = *mem_addr_ptr << 4;
1061b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *mem_addr_ptr |= fromhex (ch) & 0x0f;
1062b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1063b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1064b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while ((ch = from[i++]) != ':') {
1065b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr = *len_ptr << 4;
1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *len_ptr |= fromhex (ch) & 0x0f;
1067b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1068b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1069b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i,
1070b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                              to, *len_ptr) != *len_ptr)
1071b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return -1;
1072b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1073b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
1074b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1075b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1076b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1077b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return the path prefix for the named pipes (FIFOs) used by vgdb/gdb
1078b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to communicate with valgrind */
1079b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHChar *
1080b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_(vgdb_prefix_default)(void)
1081b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1082b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const HChar *tmpdir;
1083b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   HChar *prefix;
1084b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1085b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tmpdir = VG_(tmpdir)();
1086b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   prefix = malloc(strlen(tmpdir) + strlen("/vgdb-pipe") + 1);
1087b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   strcpy(prefix, tmpdir);
1088b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   strcat(prefix, "/vgdb-pipe");
1089b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1090b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return prefix;
1091b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1092