GDBserver
hostio.c
Go to the documentation of this file.
1 /* Host file transfer support for gdbserver.
2  Copyright (C) 2007-2015 Free Software Foundation, Inc.
3 
4  Contributed by CodeSourcery.
5 
6  This file is part of GDB.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 
21 #include "server.h"
22 #include "gdb/fileio.h"
23 #include "hostio.h"
24 
25 #include <fcntl.h>
26 #include <limits.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include "fileio.h"
31 
32 extern int remote_debug;
33 
34 struct fd_list
35 {
36  int fd;
37  struct fd_list *next;
38 };
39 
40 static struct fd_list *open_fds;
41 
42 static int
43 safe_fromhex (char a, int *nibble)
44 {
45  if (a >= '0' && a <= '9')
46  *nibble = a - '0';
47  else if (a >= 'a' && a <= 'f')
48  *nibble = a - 'a' + 10;
49  else if (a >= 'A' && a <= 'F')
50  *nibble = a - 'A' + 10;
51  else
52  return -1;
53 
54  return 0;
55 }
56 
57 /* Filenames are hex encoded, so the maximum we can handle is half the
58  packet buffer size. Cap to PATH_MAX, if it is shorter. */
59 #if !defined (PATH_MAX) || (PATH_MAX > (PBUFSIZ / 2 + 1))
60 # define HOSTIO_PATH_MAX (PBUFSIZ / 2 + 1)
61 #else
62 # define HOSTIO_PATH_MAX PATH_MAX
63 #endif
64 
65 static int
66 require_filename (char **pp, char *filename)
67 {
68  int count;
69  char *p;
70 
71  p = *pp;
72  count = 0;
73 
74  while (*p && *p != ',')
75  {
76  int nib1, nib2;
77 
78  /* Don't allow overflow. */
79  if (count >= HOSTIO_PATH_MAX - 1)
80  return -1;
81 
82  if (safe_fromhex (p[0], &nib1)
83  || safe_fromhex (p[1], &nib2))
84  return -1;
85 
86  filename[count++] = nib1 * 16 + nib2;
87  p += 2;
88  }
89 
90  filename[count] = '\0';
91  *pp = p;
92  return 0;
93 }
94 
95 static int
96 require_int (char **pp, int *value)
97 {
98  char *p;
99  int count;
100 
101  p = *pp;
102  *value = 0;
103  count = 0;
104 
105  while (*p && *p != ',')
106  {
107  int nib;
108 
109  /* Don't allow overflow. */
110  if (count >= 7)
111  return -1;
112 
113  if (safe_fromhex (p[0], &nib))
114  return -1;
115  *value = *value * 16 + nib;
116  p++;
117  count++;
118  }
119 
120  *pp = p;
121  return 0;
122 }
123 
124 static int
125 require_data (char *p, int p_len, char **data, int *data_len)
126 {
127  int input_index, output_index, escaped;
128 
129  *data = xmalloc (p_len);
130 
131  output_index = 0;
132  escaped = 0;
133  for (input_index = 0; input_index < p_len; input_index++)
134  {
135  char b = p[input_index];
136 
137  if (escaped)
138  {
139  (*data)[output_index++] = b ^ 0x20;
140  escaped = 0;
141  }
142  else if (b == '}')
143  escaped = 1;
144  else
145  (*data)[output_index++] = b;
146  }
147 
148  if (escaped)
149  {
150  free (*data);
151  return -1;
152  }
153 
154  *data_len = output_index;
155  return 0;
156 }
157 
158 static int
159 require_comma (char **pp)
160 {
161  if (**pp == ',')
162  {
163  (*pp)++;
164  return 0;
165  }
166  else
167  return -1;
168 }
169 
170 static int
171 require_end (char *p)
172 {
173  if (*p == '\0')
174  return 0;
175  else
176  return -1;
177 }
178 
179 static int
181 {
182  struct fd_list *fd_ptr;
183 
184  for (fd_ptr = open_fds; fd_ptr != NULL; fd_ptr = fd_ptr->next)
185  if (fd_ptr->fd == fd)
186  return 0;
187 
188  return -1;
189 }
190 
191 /* Fill in own_buf with the last hostio error packet, however it
192  suitable for the target. */
193 static void
195 {
196  the_target->hostio_last_error (own_buf);
197 }
198 
199 static void
201 {
202  sprintf (own_buf, "F-1,%x", FILEIO_EINVAL);
203 }
204 
205 static void
206 hostio_reply (char *own_buf, int result)
207 {
208  sprintf (own_buf, "F%x", result);
209 }
210 
211 static int
212 hostio_reply_with_data (char *own_buf, char *buffer, int len,
213  int *new_packet_len)
214 {
215  int input_index, output_index, out_maxlen;
216 
217  sprintf (own_buf, "F%x;", len);
218  output_index = strlen (own_buf);
219 
220  out_maxlen = PBUFSIZ;
221 
222  for (input_index = 0; input_index < len; input_index++)
223  {
224  char b = buffer[input_index];
225 
226  if (b == '$' || b == '#' || b == '}' || b == '*')
227  {
228  /* These must be escaped. */
229  if (output_index + 2 > out_maxlen)
230  break;
231  own_buf[output_index++] = '}';
232  own_buf[output_index++] = b ^ 0x20;
233  }
234  else
235  {
236  if (output_index + 1 > out_maxlen)
237  break;
238  own_buf[output_index++] = b;
239  }
240  }
241 
242  *new_packet_len = output_index;
243  return input_index;
244 }
245 
246 /* Process ID of inferior whose filesystem hostio functions
247  that take FILENAME arguments will use. Zero means to use
248  our own filesystem. */
249 
250 static int hostio_fs_pid;
251 
252 /* See hostio.h. */
253 
254 void
256 {
257  hostio_fs_pid = 0;
258 }
259 
260 /* Handle a "vFile:setfs:" packet. */
261 
262 static void
264 {
265  char *p;
266  int pid;
267 
268  /* If the target doesn't have any of the in-filesystem-of methods
269  then there's no point in GDB sending "vFile:setfs:" packets. We
270  reply with an empty packet (i.e. we pretend we don't understand
271  "vFile:setfs:") and that should stop GDB sending any more. */
272  if (the_target->multifs_open == NULL
273  && the_target->multifs_unlink == NULL
274  && the_target->multifs_readlink == NULL)
275  {
276  own_buf[0] = '\0';
277  return;
278  }
279 
280  p = own_buf + strlen ("vFile:setfs:");
281 
282  if (require_int (&p, &pid)
283  || pid < 0
284  || require_end (p))
285  {
286  hostio_packet_error (own_buf);
287  return;
288  }
289 
290  hostio_fs_pid = pid;
291 
292  hostio_reply (own_buf, 0);
293 }
294 
295 static void
297 {
298  char filename[HOSTIO_PATH_MAX];
299  char *p;
300  int fileio_flags, fileio_mode, flags, fd;
301  mode_t mode;
302  struct fd_list *new_fd;
303 
304  p = own_buf + strlen ("vFile:open:");
305 
306  if (require_filename (&p, filename)
307  || require_comma (&p)
308  || require_int (&p, &fileio_flags)
309  || require_comma (&p)
310  || require_int (&p, &fileio_mode)
311  || require_end (p)
312  || fileio_to_host_openflags (fileio_flags, &flags)
313  || fileio_to_host_mode (fileio_mode, &mode))
314  {
315  hostio_packet_error (own_buf);
316  return;
317  }
318 
319  /* We do not need to convert MODE, since the fileio protocol
320  uses the standard values. */
321  if (hostio_fs_pid != 0 && the_target->multifs_open != NULL)
322  fd = the_target->multifs_open (hostio_fs_pid, filename,
323  flags, mode);
324  else
325  fd = open (filename, flags, mode);
326 
327  if (fd == -1)
328  {
329  hostio_error (own_buf);
330  return;
331  }
332 
333  /* Record the new file descriptor. */
334  new_fd = xmalloc (sizeof (struct fd_list));
335  new_fd->fd = fd;
336  new_fd->next = open_fds;
337  open_fds = new_fd;
338 
339  hostio_reply (own_buf, fd);
340 }
341 
342 static void
343 handle_pread (char *own_buf, int *new_packet_len)
344 {
345  int fd, ret, len, offset, bytes_sent;
346  char *p, *data;
347  static int max_reply_size = -1;
348 
349  p = own_buf + strlen ("vFile:pread:");
350 
351  if (require_int (&p, &fd)
352  || require_comma (&p)
353  || require_valid_fd (fd)
354  || require_int (&p, &len)
355  || require_comma (&p)
356  || require_int (&p, &offset)
357  || require_end (p))
358  {
359  hostio_packet_error (own_buf);
360  return;
361  }
362 
363  /* Do not attempt to read more than the maximum number of bytes
364  hostio_reply_with_data can fit in a packet. We may still read
365  too much because of escaping, but this is handled below. */
366  if (max_reply_size == -1)
367  {
368  sprintf (own_buf, "F%x;", PBUFSIZ);
369  max_reply_size = PBUFSIZ - strlen (own_buf);
370  }
371  if (len > max_reply_size)
372  len = max_reply_size;
373 
374  data = xmalloc (len);
375 #ifdef HAVE_PREAD
376  ret = pread (fd, data, len, offset);
377 #else
378  ret = -1;
379 #endif
380  /* If we have no pread or it failed for this file, use lseek/read. */
381  if (ret == -1)
382  {
383  ret = lseek (fd, offset, SEEK_SET);
384  if (ret != -1)
385  ret = read (fd, data, len);
386  }
387 
388  if (ret == -1)
389  {
390  hostio_error (own_buf);
391  free (data);
392  return;
393  }
394 
395  bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len);
396 
397  /* If we were using read, and the data did not all fit in the reply,
398  we would have to back up using lseek here. With pread it does
399  not matter. But we still have a problem; the return value in the
400  packet might be wrong, so we must fix it. This time it will
401  definitely fit. */
402  if (bytes_sent < ret)
403  bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent,
404  new_packet_len);
405 
406  free (data);
407 }
408 
409 static void
410 handle_pwrite (char *own_buf, int packet_len)
411 {
412  int fd, ret, len, offset;
413  char *p, *data;
414 
415  p = own_buf + strlen ("vFile:pwrite:");
416 
417  if (require_int (&p, &fd)
418  || require_comma (&p)
419  || require_valid_fd (fd)
420  || require_int (&p, &offset)
421  || require_comma (&p)
422  || require_data (p, packet_len - (p - own_buf), &data, &len))
423  {
424  hostio_packet_error (own_buf);
425  return;
426  }
427 
428 #ifdef HAVE_PWRITE
429  ret = pwrite (fd, data, len, offset);
430 #else
431  ret = -1;
432 #endif
433  /* If we have no pwrite or it failed for this file, use lseek/write. */
434  if (ret == -1)
435  {
436  ret = lseek (fd, offset, SEEK_SET);
437  if (ret != -1)
438  ret = write (fd, data, len);
439  }
440 
441  if (ret == -1)
442  {
443  hostio_error (own_buf);
444  free (data);
445  return;
446  }
447 
448  hostio_reply (own_buf, ret);
449  free (data);
450 }
451 
452 static void
453 handle_fstat (char *own_buf, int *new_packet_len)
454 {
455  int fd, bytes_sent;
456  char *p;
457  struct stat st;
458  struct fio_stat fst;
459 
460  p = own_buf + strlen ("vFile:fstat:");
461 
462  if (require_int (&p, &fd)
463  || require_valid_fd (fd)
464  || require_end (p))
465  {
466  hostio_packet_error (own_buf);
467  return;
468  }
469 
470  if (fstat (fd, &st) == -1)
471  {
472  hostio_error (own_buf);
473  return;
474  }
475 
476  host_to_fileio_stat (&st, &fst);
477 
478  bytes_sent = hostio_reply_with_data (own_buf,
479  (char *) &fst, sizeof (fst),
480  new_packet_len);
481 
482  /* If the response does not fit into a single packet, do not attempt
483  to return a partial response, but simply fail. */
484  if (bytes_sent < sizeof (fst))
485  write_enn (own_buf);
486 }
487 
488 static void
490 {
491  int fd, ret;
492  char *p;
493  struct fd_list **open_fd_p, *old_fd;
494 
495  p = own_buf + strlen ("vFile:close:");
496 
497  if (require_int (&p, &fd)
498  || require_valid_fd (fd)
499  || require_end (p))
500  {
501  hostio_packet_error (own_buf);
502  return;
503  }
504 
505  ret = close (fd);
506 
507  if (ret == -1)
508  {
509  hostio_error (own_buf);
510  return;
511  }
512 
513  open_fd_p = &open_fds;
514  /* We know that fd is in the list, thanks to require_valid_fd. */
515  while ((*open_fd_p)->fd != fd)
516  open_fd_p = &(*open_fd_p)->next;
517 
518  old_fd = *open_fd_p;
519  *open_fd_p = (*open_fd_p)->next;
520  free (old_fd);
521 
522  hostio_reply (own_buf, ret);
523 }
524 
525 static void
527 {
528  char filename[HOSTIO_PATH_MAX];
529  char *p;
530  int ret;
531 
532  p = own_buf + strlen ("vFile:unlink:");
533 
534  if (require_filename (&p, filename)
535  || require_end (p))
536  {
537  hostio_packet_error (own_buf);
538  return;
539  }
540 
541  if (hostio_fs_pid != 0 && the_target->multifs_unlink != NULL)
542  ret = the_target->multifs_unlink (hostio_fs_pid, filename);
543  else
544  ret = unlink (filename);
545 
546  if (ret == -1)
547  {
548  hostio_error (own_buf);
549  return;
550  }
551 
552  hostio_reply (own_buf, ret);
553 }
554 
555 static void
556 handle_readlink (char *own_buf, int *new_packet_len)
557 {
558  char filename[HOSTIO_PATH_MAX], linkname[HOSTIO_PATH_MAX];
559  char *p;
560  int ret, bytes_sent;
561 
562  p = own_buf + strlen ("vFile:readlink:");
563 
564  if (require_filename (&p, filename)
565  || require_end (p))
566  {
567  hostio_packet_error (own_buf);
568  return;
569  }
570 
571  if (hostio_fs_pid != 0 && the_target->multifs_readlink != NULL)
572  ret = the_target->multifs_readlink (hostio_fs_pid, filename,
573  linkname,
574  sizeof (linkname) - 1);
575  else
576  ret = readlink (filename, linkname, sizeof (linkname) - 1);
577 
578  if (ret == -1)
579  {
580  hostio_error (own_buf);
581  return;
582  }
583 
584  bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len);
585 
586  /* If the response does not fit into a single packet, do not attempt
587  to return a partial response, but simply fail. */
588  if (bytes_sent < ret)
589  sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG);
590 }
591 
592 /* Handle all the 'F' file transfer packets. */
593 
594 int
595 handle_vFile (char *own_buf, int packet_len, int *new_packet_len)
596 {
597  if (startswith (own_buf, "vFile:open:"))
598  handle_open (own_buf);
599  else if (startswith (own_buf, "vFile:pread:"))
600  handle_pread (own_buf, new_packet_len);
601  else if (startswith (own_buf, "vFile:pwrite:"))
602  handle_pwrite (own_buf, packet_len);
603  else if (startswith (own_buf, "vFile:fstat:"))
604  handle_fstat (own_buf, new_packet_len);
605  else if (startswith (own_buf, "vFile:close:"))
606  handle_close (own_buf);
607  else if (startswith (own_buf, "vFile:unlink:"))
608  handle_unlink (own_buf);
609  else if (startswith (own_buf, "vFile:readlink:"))
610  handle_readlink (own_buf, new_packet_len);
611  else if (startswith (own_buf, "vFile:setfs:"))
612  handle_setfs (own_buf);
613  else
614  return 0;
615 
616  return 1;
617 }
int(* multifs_open)(int pid, const char *filename, int flags, mode_t mode)
Definition: target.h:423
static int require_filename(char **pp, char *filename)
Definition: hostio.c:66
static struct fd_list * open_fds
Definition: hostio.c:40
int fileio_to_host_mode(int fileio_mode, mode_t *mode_p)
Definition: fileio.c:115
static int require_comma(char **pp)
Definition: hostio.c:159
static int require_int(char **pp, int *value)
Definition: hostio.c:96
struct fd_list * next
Definition: hostio.c:37
static int require_end(char *p)
Definition: hostio.c:171
static void handle_unlink(char *own_buf)
Definition: hostio.c:526
static void handle_readlink(char *own_buf, int *new_packet_len)
Definition: hostio.c:556
struct target_ops * the_target
Definition: target.c:24
void hostio_handle_new_gdb_connection(void)
Definition: hostio.c:255
int fileio_to_host_openflags(int fileio_open_flags, int *open_flags_p)
Definition: fileio.c:81
static void handle_pwrite(char *own_buf, int packet_len)
Definition: hostio.c:410
Definition: hostio.c:34
static void handle_fstat(char *own_buf, int *new_packet_len)
Definition: hostio.c:453
static void hostio_error(char *own_buf)
Definition: hostio.c:194
int offset
Definition: tracepoint.c:179
void host_to_fileio_stat(struct stat *st, struct fio_stat *fst)
Definition: fileio.c:224
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:75
int(* multifs_unlink)(int pid, const char *filename)
Definition: target.h:430
static void hostio_packet_error(char *own_buf)
Definition: hostio.c:200
static void handle_close(char *own_buf)
Definition: hostio.c:489
int handle_vFile(char *own_buf, int packet_len, int *new_packet_len)
Definition: hostio.c:595
static void handle_open(char *own_buf)
Definition: hostio.c:296
static int require_data(char *p, int p_len, char **data, int *data_len)
Definition: hostio.c:125
int fd
Definition: hostio.c:36
#define HOSTIO_PATH_MAX
Definition: hostio.c:60
static int hostio_reply_with_data(char *own_buf, char *buffer, int len, int *new_packet_len)
Definition: hostio.c:212
ssize_t(* multifs_readlink)(int pid, const char *filename, char *buf, size_t bufsiz)
Definition: target.h:437
static int safe_fromhex(char a, int *nibble)
Definition: hostio.c:43
static char * own_buf
Definition: server.c:111
Definition: buffer.h:23
static void handle_setfs(char *own_buf)
Definition: hostio.c:263
int remote_debug
Definition: remote-utils.c:103
static void hostio_reply(char *own_buf, int result)
Definition: hostio.c:206
static void handle_pread(char *own_buf, int *new_packet_len)
Definition: hostio.c:343
PTR xmalloc(size_t size)
Definition: common-utils.c:34
#define PBUFSIZ
Definition: server.h:129
static int require_valid_fd(int fd)
Definition: hostio.c:180
static int hostio_fs_pid
Definition: hostio.c:250
void write_enn(char *buf)
void(* hostio_last_error)(char *buf)
Definition: target.h:259