hostio.cc 13 KB

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