* elf64-ppc.c (dec_dynrel_count): Don't error when elf_gc_sweep_symbol
[external/binutils.git] / gdb / gdbserver / hostio.c
1 /* Host file transfer support for gdbserver.
2    Copyright (C) 2007-2013 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
24 #include <fcntl.h>
25 #include <limits.h>
26 #include <unistd.h>
27
28 extern int remote_debug;
29
30 struct fd_list
31 {
32   int fd;
33   struct fd_list *next;
34 };
35
36 static struct fd_list *open_fds;
37
38 static int
39 safe_fromhex (char a, int *nibble)
40 {
41   if (a >= '0' && a <= '9')
42     *nibble = a - '0';
43   else if (a >= 'a' && a <= 'f')
44     *nibble = a - 'a' + 10;
45   else if (a >= 'A' && a <= 'F')
46     *nibble = a - 'A' + 10;
47   else
48     return -1;
49
50   return 0;
51 }
52
53 static int
54 require_filename (char **pp, char *filename)
55 {
56   int count;
57   char *p;
58
59   p = *pp;
60   count = 0;
61
62   while (*p && *p != ',')
63     {
64       int nib1, nib2;
65
66       /* Don't allow overflow.  */
67       if (count >= PATH_MAX - 1)
68         return -1;
69
70       if (safe_fromhex (p[0], &nib1)
71           || safe_fromhex (p[1], &nib2))
72         return -1;
73
74       filename[count++] = nib1 * 16 + nib2;
75       p += 2;
76     }
77
78   filename[count] = '\0';
79   *pp = p;
80   return 0;
81 }
82
83 static int
84 require_int (char **pp, int *value)
85 {
86   char *p;
87   int count;
88
89   p = *pp;
90   *value = 0;
91   count = 0;
92
93   while (*p && *p != ',')
94     {
95       int nib;
96
97       /* Don't allow overflow.  */
98       if (count >= 7)
99         return -1;
100
101       if (safe_fromhex (p[0], &nib))
102         return -1;
103       *value = *value * 16 + nib;
104       p++;
105       count++;
106     }
107
108   *pp = p;
109   return 0;
110 }
111
112 static int
113 require_data (char *p, int p_len, char **data, int *data_len)
114 {
115   int input_index, output_index, escaped;
116
117   *data = xmalloc (p_len);
118
119   output_index = 0;
120   escaped = 0;
121   for (input_index = 0; input_index < p_len; input_index++)
122     {
123       char b = p[input_index];
124
125       if (escaped)
126         {
127           (*data)[output_index++] = b ^ 0x20;
128           escaped = 0;
129         }
130       else if (b == '}')
131         escaped = 1;
132       else
133         (*data)[output_index++] = b;
134     }
135
136   if (escaped)
137     {
138       free (*data);
139       return -1;
140     }
141
142   *data_len = output_index;
143   return 0;
144 }
145
146 static int
147 require_comma (char **pp)
148 {
149   if (**pp == ',')
150     {
151       (*pp)++;
152       return 0;
153     }
154   else
155     return -1;
156 }
157
158 static int
159 require_end (char *p)
160 {
161   if (*p == '\0')
162     return 0;
163   else
164     return -1;
165 }
166
167 static int
168 require_valid_fd (int fd)
169 {
170   struct fd_list *fd_ptr;
171
172   for (fd_ptr = open_fds; fd_ptr != NULL; fd_ptr = fd_ptr->next)
173     if (fd_ptr->fd == fd)
174       return 0;
175
176   return -1;
177 }
178
179 /* Fill in own_buf with the last hostio error packet, however it
180    suitable for the target.  */
181 static void
182 hostio_error (char *own_buf)
183 {
184   the_target->hostio_last_error (own_buf);
185 }
186
187 static void
188 hostio_packet_error (char *own_buf)
189 {
190   sprintf (own_buf, "F-1,%x", FILEIO_EINVAL);
191 }
192
193 static void
194 hostio_reply (char *own_buf, int result)
195 {
196   sprintf (own_buf, "F%x", result);
197 }
198
199 static int
200 hostio_reply_with_data (char *own_buf, char *buffer, int len,
201                         int *new_packet_len)
202 {
203   int input_index, output_index, out_maxlen;
204
205   sprintf (own_buf, "F%x;", len);
206   output_index = strlen (own_buf);
207
208   out_maxlen = PBUFSIZ;
209
210   for (input_index = 0; input_index < len; input_index++)
211     {
212       char b = buffer[input_index];
213
214       if (b == '$' || b == '#' || b == '}' || b == '*')
215         {
216           /* These must be escaped.  */
217           if (output_index + 2 > out_maxlen)
218             break;
219           own_buf[output_index++] = '}';
220           own_buf[output_index++] = b ^ 0x20;
221         }
222       else
223         {
224           if (output_index + 1 > out_maxlen)
225             break;
226           own_buf[output_index++] = b;
227         }
228     }
229
230   *new_packet_len = output_index;
231   return input_index;
232 }
233
234 static int
235 fileio_open_flags_to_host (int fileio_open_flags, int *open_flags_p)
236 {
237   int open_flags = 0;
238
239   if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
240     return -1;
241
242   if (fileio_open_flags & FILEIO_O_CREAT)
243     open_flags |= O_CREAT;
244   if (fileio_open_flags & FILEIO_O_EXCL)
245     open_flags |= O_EXCL;
246   if (fileio_open_flags & FILEIO_O_TRUNC)
247     open_flags |= O_TRUNC;
248   if (fileio_open_flags & FILEIO_O_APPEND)
249     open_flags |= O_APPEND;
250   if (fileio_open_flags & FILEIO_O_RDONLY)
251     open_flags |= O_RDONLY;
252   if (fileio_open_flags & FILEIO_O_WRONLY)
253     open_flags |= O_WRONLY;
254   if (fileio_open_flags & FILEIO_O_RDWR)
255     open_flags |= O_RDWR;
256 /* On systems supporting binary and text mode, always open files in
257    binary mode. */
258 #ifdef O_BINARY
259   open_flags |= O_BINARY;
260 #endif
261
262   *open_flags_p = open_flags;
263   return 0;
264 }
265
266 static void
267 handle_open (char *own_buf)
268 {
269   char filename[PATH_MAX];
270   char *p;
271   int fileio_flags, mode, flags, fd;
272   struct fd_list *new_fd;
273
274   p = own_buf + strlen ("vFile:open:");
275
276   if (require_filename (&p, filename)
277       || require_comma (&p)
278       || require_int (&p, &fileio_flags)
279       || require_comma (&p)
280       || require_int (&p, &mode)
281       || require_end (p)
282       || fileio_open_flags_to_host (fileio_flags, &flags))
283     {
284       hostio_packet_error (own_buf);
285       return;
286     }
287
288   /* We do not need to convert MODE, since the fileio protocol
289      uses the standard values.  */
290   fd = open (filename, flags, mode);
291
292   if (fd == -1)
293     {
294       hostio_error (own_buf);
295       return;
296     }
297
298   /* Record the new file descriptor.  */
299   new_fd = xmalloc (sizeof (struct fd_list));
300   new_fd->fd = fd;
301   new_fd->next = open_fds;
302   open_fds = new_fd;
303
304   hostio_reply (own_buf, fd);
305 }
306
307 static void
308 handle_pread (char *own_buf, int *new_packet_len)
309 {
310   int fd, ret, len, offset, bytes_sent;
311   char *p, *data;
312
313   p = own_buf + strlen ("vFile:pread:");
314
315   if (require_int (&p, &fd)
316       || require_comma (&p)
317       || require_valid_fd (fd)
318       || require_int (&p, &len)
319       || require_comma (&p)
320       || require_int (&p, &offset)
321       || require_end (p))
322     {
323       hostio_packet_error (own_buf);
324       return;
325     }
326
327   data = xmalloc (len);
328 #ifdef HAVE_PREAD
329   ret = pread (fd, data, len, offset);
330 #else
331   ret = -1;
332 #endif
333   /* If we have no pread or it failed for this file, use lseek/read.  */
334   if (ret == -1)
335     {
336       ret = lseek (fd, offset, SEEK_SET);
337       if (ret != -1)
338         ret = read (fd, data, len);
339     }
340
341   if (ret == -1)
342     {
343       hostio_error (own_buf);
344       free (data);
345       return;
346     }
347
348   bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len);
349
350   /* If we were using read, and the data did not all fit in the reply,
351      we would have to back up using lseek here.  With pread it does
352      not matter.  But we still have a problem; the return value in the
353      packet might be wrong, so we must fix it.  This time it will
354      definitely fit.  */
355   if (bytes_sent < ret)
356     bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent,
357                                          new_packet_len);
358
359   free (data);
360 }
361
362 static void
363 handle_pwrite (char *own_buf, int packet_len)
364 {
365   int fd, ret, len, offset;
366   char *p, *data;
367
368   p = own_buf + strlen ("vFile:pwrite:");
369
370   if (require_int (&p, &fd)
371       || require_comma (&p)
372       || require_valid_fd (fd)
373       || require_int (&p, &offset)
374       || require_comma (&p)
375       || require_data (p, packet_len - (p - own_buf), &data, &len))
376     {
377       hostio_packet_error (own_buf);
378       return;
379     }
380
381 #ifdef HAVE_PWRITE
382   ret = pwrite (fd, data, len, offset);
383 #else
384   ret = -1;
385 #endif
386   /* If we have no pwrite or it failed for this file, use lseek/write.  */
387   if (ret == -1)
388     {
389       ret = lseek (fd, offset, SEEK_SET);
390       if (ret != -1)
391         ret = write (fd, data, len);
392     }
393
394   if (ret == -1)
395     {
396       hostio_error (own_buf);
397       free (data);
398       return;
399     }
400
401   hostio_reply (own_buf, ret);
402   free (data);
403 }
404
405 static void
406 handle_close (char *own_buf)
407 {
408   int fd, ret;
409   char *p;
410   struct fd_list **open_fd_p, *old_fd;
411
412   p = own_buf + strlen ("vFile:close:");
413
414   if (require_int (&p, &fd)
415       || require_valid_fd (fd)
416       || require_end (p))
417     {
418       hostio_packet_error (own_buf);
419       return;
420     }
421
422   ret = close (fd);
423
424   if (ret == -1)
425     {
426       hostio_error (own_buf);
427       return;
428     }
429
430   open_fd_p = &open_fds;
431   /* We know that fd is in the list, thanks to require_valid_fd.  */
432   while ((*open_fd_p)->fd != fd)
433     open_fd_p = &(*open_fd_p)->next;
434
435   old_fd = *open_fd_p;
436   *open_fd_p = (*open_fd_p)->next;
437   free (old_fd);
438
439   hostio_reply (own_buf, ret);
440 }
441
442 static void
443 handle_unlink (char *own_buf)
444 {
445   char filename[PATH_MAX];
446   char *p;
447   int ret;
448
449   p = own_buf + strlen ("vFile:unlink:");
450
451   if (require_filename (&p, filename)
452       || require_end (p))
453     {
454       hostio_packet_error (own_buf);
455       return;
456     }
457
458   ret = unlink (filename);
459
460   if (ret == -1)
461     {
462       hostio_error (own_buf);
463       return;
464     }
465
466   hostio_reply (own_buf, ret);
467 }
468
469 static void
470 handle_readlink (char *own_buf, int *new_packet_len)
471 {
472 #if defined (HAVE_READLINK)
473   char filename[PATH_MAX], linkname[PATH_MAX];
474   char *p;
475   int ret, bytes_sent;
476
477   p = own_buf + strlen ("vFile:readlink:");
478
479   if (require_filename (&p, filename)
480       || require_end (p))
481     {
482       hostio_packet_error (own_buf);
483       return;
484     }
485
486   ret = readlink (filename, linkname, sizeof (linkname) - 1);
487   if (ret == -1)
488     {
489       hostio_error (own_buf);
490       return;
491     }
492
493   bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len);
494
495   /* If the response does not fit into a single packet, do not attempt
496      to return a partial response, but simply fail.  */
497   if (bytes_sent < ret)
498     sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG);
499 #else /* ! HAVE_READLINK */
500     sprintf (own_buf, "F-1,%x", FILEIO_ENOSYS);
501 #endif
502 }
503
504 /* Handle all the 'F' file transfer packets.  */
505
506 int
507 handle_vFile (char *own_buf, int packet_len, int *new_packet_len)
508 {
509   if (strncmp (own_buf, "vFile:open:", 11) == 0)
510     handle_open (own_buf);
511   else if (strncmp (own_buf, "vFile:pread:", 11) == 0)
512     handle_pread (own_buf, new_packet_len);
513   else if (strncmp (own_buf, "vFile:pwrite:", 12) == 0)
514     handle_pwrite (own_buf, packet_len);
515   else if (strncmp (own_buf, "vFile:close:", 12) == 0)
516     handle_close (own_buf);
517   else if (strncmp (own_buf, "vFile:unlink:", 13) == 0)
518     handle_unlink (own_buf);
519   else if (strncmp (own_buf, "vFile:readlink:", 15) == 0)
520     handle_readlink (own_buf, new_packet_len);
521   else
522     return 0;
523
524   return 1;
525 }