You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1642 lines
50 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2018 by Liviu Ionescu *
  3. * <ilg@livius.net> *
  4. * *
  5. * Copyright (C) 2018 by Marvell Technology Group Ltd. *
  6. * Written by Nicolas Pitre <nico@marvell.com> *
  7. * *
  8. * Copyright (C) 2010 by Spencer Oliver *
  9. * spen@spen-soft.co.uk *
  10. * *
  11. * Copyright (C) 2016 by Square, Inc. *
  12. * Steven Stallion <stallion@squareup.com> *
  13. * *
  14. * This program is free software; you can redistribute it and/or modify *
  15. * it under the terms of the GNU General Public License as published by *
  16. * the Free Software Foundation; either version 2 of the License, or *
  17. * (at your option) any later version. *
  18. * *
  19. * This program is distributed in the hope that it will be useful, *
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  22. * GNU General Public License for more details. *
  23. * *
  24. * You should have received a copy of the GNU General Public License *
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  26. ***************************************************************************/
  27. /**
  28. * @file
  29. * Common ARM semihosting support.
  30. *
  31. * Semihosting enables code running on a target to use some of the I/O
  32. * facilities on the host computer. The target application must be linked
  33. * against a library that forwards operation requests by using an
  34. * instruction trapped by the debugger.
  35. *
  36. * Details can be found in
  37. * "Semihosting for AArch32 and AArch64, Release 2.0"
  38. * https://static.docs.arm.com/100863/0200/semihosting.pdf
  39. * from ARM Ltd.
  40. */
  41. #ifdef HAVE_CONFIG_H
  42. #include "config.h"
  43. #endif
  44. #include "target.h"
  45. #include "target_type.h"
  46. #include "semihosting_common.h"
  47. #include <helper/binarybuffer.h>
  48. #include <helper/log.h>
  49. #include <sys/stat.h>
  50. static const int open_modeflags[12] = {
  51. O_RDONLY,
  52. O_RDONLY | O_BINARY,
  53. O_RDWR,
  54. O_RDWR | O_BINARY,
  55. O_WRONLY | O_CREAT | O_TRUNC,
  56. O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
  57. O_RDWR | O_CREAT | O_TRUNC,
  58. O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
  59. O_WRONLY | O_CREAT | O_APPEND,
  60. O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
  61. O_RDWR | O_CREAT | O_APPEND,
  62. O_RDWR | O_CREAT | O_APPEND | O_BINARY
  63. };
  64. static int semihosting_common_fileio_info(struct target *target,
  65. struct gdb_fileio_info *fileio_info);
  66. static int semihosting_common_fileio_end(struct target *target, int result,
  67. int fileio_errno, bool ctrl_c);
  68. static int semihosting_read_fields(struct target *target, size_t number,
  69. uint8_t *fields);
  70. static int semihosting_write_fields(struct target *target, size_t number,
  71. uint8_t *fields);
  72. static uint64_t semihosting_get_field(struct target *target, size_t index,
  73. uint8_t *fields);
  74. static void semihosting_set_field(struct target *target, uint64_t value,
  75. size_t index,
  76. uint8_t *fields);
  77. /* Attempts to include gdb_server.h failed. */
  78. extern int gdb_actual_connections;
  79. /**
  80. * Initialize common semihosting support.
  81. *
  82. * @param target Pointer to the target to initialize.
  83. * @param setup
  84. * @param post_result
  85. * @return An error status if there is a problem during initialization.
  86. */
  87. int semihosting_common_init(struct target *target, void *setup,
  88. void *post_result)
  89. {
  90. LOG_DEBUG(" ");
  91. target->fileio_info = malloc(sizeof(*target->fileio_info));
  92. if (!target->fileio_info) {
  93. LOG_ERROR("out of memory");
  94. return ERROR_FAIL;
  95. }
  96. memset(target->fileio_info, 0, sizeof(*target->fileio_info));
  97. struct semihosting *semihosting;
  98. semihosting = malloc(sizeof(*target->semihosting));
  99. if (!semihosting) {
  100. LOG_ERROR("out of memory");
  101. return ERROR_FAIL;
  102. }
  103. semihosting->is_active = false;
  104. semihosting->is_fileio = false;
  105. semihosting->hit_fileio = false;
  106. semihosting->is_resumable = false;
  107. semihosting->has_resumable_exit = false;
  108. semihosting->word_size_bytes = 0;
  109. semihosting->op = -1;
  110. semihosting->param = 0;
  111. semihosting->result = -1;
  112. semihosting->sys_errno = -1;
  113. semihosting->cmdline = NULL;
  114. /* If possible, update it in setup(). */
  115. semihosting->setup_time = clock();
  116. semihosting->setup = setup;
  117. semihosting->post_result = post_result;
  118. target->semihosting = semihosting;
  119. target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
  120. target->type->gdb_fileio_end = semihosting_common_fileio_end;
  121. return ERROR_OK;
  122. }
  123. /**
  124. * Portable implementation of ARM semihosting calls.
  125. * Performs the currently pending semihosting operation
  126. * encoded in target->semihosting.
  127. */
  128. int semihosting_common(struct target *target)
  129. {
  130. struct semihosting *semihosting = target->semihosting;
  131. if (!semihosting) {
  132. /* Silently ignore if the semihosting field was not set. */
  133. return ERROR_OK;
  134. }
  135. struct gdb_fileio_info *fileio_info = target->fileio_info;
  136. /*
  137. * By default return an error.
  138. * The actual result must be set by each function
  139. */
  140. semihosting->result = -1;
  141. /* Most operations are resumable, except the two exit calls. */
  142. semihosting->is_resumable = true;
  143. int retval;
  144. /* Enough space to hold 4 long words. */
  145. uint8_t fields[4*8];
  146. LOG_DEBUG("op=0x%x, param=0x%" PRIx64, (int)semihosting->op,
  147. semihosting->param);
  148. switch (semihosting->op) {
  149. case SEMIHOSTING_SYS_CLOCK: /* 0x10 */
  150. /*
  151. * Returns the number of centiseconds (hundredths of a second)
  152. * since the execution started.
  153. *
  154. * Values returned can be of limited use for some benchmarking
  155. * purposes because of communication overhead or other
  156. * agent-specific factors. For example, with a debug hardware
  157. * unit the request is passed back to the host for execution.
  158. * This can lead to unpredictable delays in transmission and
  159. * process scheduling.
  160. *
  161. * Use this function to calculate time intervals, by calculating
  162. * differences between intervals with and without the code
  163. * sequence to be timed.
  164. *
  165. * Entry
  166. * The PARAMETER REGISTER must contain 0. There are no other
  167. * parameters.
  168. *
  169. * Return
  170. * On exit, the RETURN REGISTER contains:
  171. * - The number of centiseconds since some arbitrary start
  172. * point, if the call is successful.
  173. * - –1 if the call is not successful. For example, because
  174. * of a communications error.
  175. */
  176. {
  177. clock_t delta = clock() - semihosting->setup_time;
  178. semihosting->result = delta / (CLOCKS_PER_SEC / 100);
  179. }
  180. break;
  181. case SEMIHOSTING_SYS_CLOSE: /* 0x02 */
  182. /*
  183. * Closes a file on the host system. The handle must reference
  184. * a file that was opened with SYS_OPEN.
  185. *
  186. * Entry
  187. * On entry, the PARAMETER REGISTER contains a pointer to a
  188. * one-field argument block:
  189. * - field 1 Contains a handle for an open file.
  190. *
  191. * Return
  192. * On exit, the RETURN REGISTER contains:
  193. * - 0 if the call is successful
  194. * - –1 if the call is not successful.
  195. */
  196. retval = semihosting_read_fields(target, 1, fields);
  197. if (retval != ERROR_OK)
  198. return retval;
  199. else {
  200. int fd = semihosting_get_field(target, 0, fields);
  201. /* Do not allow to close OpenOCD's own standard streams */
  202. if (fd == 0 || fd == 1 || fd == 2) {
  203. LOG_DEBUG("ignoring semihosting attempt to close %s",
  204. (fd == 0) ? "stdin" :
  205. (fd == 1) ? "stdout" : "stderr");
  206. /* Just pretend success */
  207. if (semihosting->is_fileio) {
  208. semihosting->result = 0;
  209. } else {
  210. semihosting->result = 0;
  211. semihosting->sys_errno = 0;
  212. }
  213. break;
  214. }
  215. /* Close the descriptor */
  216. if (semihosting->is_fileio) {
  217. semihosting->hit_fileio = true;
  218. fileio_info->identifier = "close";
  219. fileio_info->param_1 = fd;
  220. } else {
  221. semihosting->result = close(fd);
  222. semihosting->sys_errno = errno;
  223. LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
  224. }
  225. }
  226. break;
  227. case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
  228. /*
  229. * Returns the value of the C library errno variable that is
  230. * associated with the semihosting implementation. The errno
  231. * variable can be set by a number of C library semihosted
  232. * functions, including:
  233. * - SYS_REMOVE
  234. * - SYS_OPEN
  235. * - SYS_CLOSE
  236. * - SYS_READ
  237. * - SYS_WRITE
  238. * - SYS_SEEK.
  239. *
  240. * Whether errno is set or not, and to what value, is entirely
  241. * host-specific, except where the ISO C standard defines the
  242. * behavior.
  243. *
  244. * Entry
  245. * There are no parameters. The PARAMETER REGISTER must be 0.
  246. *
  247. * Return
  248. * On exit, the RETURN REGISTER contains the value of the C
  249. * library errno variable.
  250. */
  251. semihosting->result = semihosting->sys_errno;
  252. break;
  253. case SEMIHOSTING_SYS_EXIT: /* 0x18 */
  254. /*
  255. * Note: SYS_EXIT was called angel_SWIreason_ReportException in
  256. * previous versions of the documentation.
  257. *
  258. * An application calls this operation to report an exception
  259. * to the debugger directly. The most common use is to report
  260. * that execution has completed, using ADP_Stopped_ApplicationExit.
  261. *
  262. * Note: This semihosting operation provides no means for 32-bit
  263. * callers to indicate an application exit with a specified exit
  264. * code. Semihosting callers may prefer to check for the presence
  265. * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
  266. * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
  267. * is available.
  268. *
  269. * Entry (32-bit)
  270. * On entry, the PARAMETER register is set to a reason code
  271. * describing the cause of the trap. Not all semihosting client
  272. * implementations will necessarily trap every corresponding
  273. * event. Important reason codes are:
  274. *
  275. * - ADP_Stopped_ApplicationExit 0x20026
  276. * - ADP_Stopped_RunTimeErrorUnknown 0x20023
  277. *
  278. * Entry (64-bit)
  279. * On entry, the PARAMETER REGISTER contains a pointer to a
  280. * two-field argument block:
  281. * - field 1 The exception type, which is one of the set of
  282. * reason codes in the above tables.
  283. * - field 2 A subcode, whose meaning depends on the reason
  284. * code in field 1.
  285. * In particular, if field 1 is ADP_Stopped_ApplicationExit
  286. * then field 2 is an exit status code, as passed to the C
  287. * standard library exit() function. A simulator receiving
  288. * this request must notify a connected debugger, if present,
  289. * and then exit with the specified status.
  290. *
  291. * Return
  292. * No return is expected from these calls. However, it is
  293. * possible for the debugger to request that the application
  294. * continues by performing an RDI_Execute request or equivalent.
  295. * In this case, execution continues with the registers as they
  296. * were on entry to the operation, or as subsequently modified
  297. * by the debugger.
  298. */
  299. if (semihosting->word_size_bytes == 8) {
  300. retval = semihosting_read_fields(target, 2, fields);
  301. if (retval != ERROR_OK)
  302. return retval;
  303. else {
  304. int type = semihosting_get_field(target, 0, fields);
  305. int code = semihosting_get_field(target, 1, fields);
  306. if (type == ADP_STOPPED_APPLICATION_EXIT) {
  307. if (!gdb_actual_connections)
  308. exit(code);
  309. else {
  310. fprintf(stderr,
  311. "semihosting: *** application exited with %d ***\n",
  312. code);
  313. }
  314. } else {
  315. fprintf(stderr,
  316. "semihosting: application exception %#x\n",
  317. type);
  318. }
  319. }
  320. } else {
  321. if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
  322. if (!gdb_actual_connections)
  323. exit(0);
  324. else {
  325. fprintf(stderr,
  326. "semihosting: *** application exited normally ***\n");
  327. }
  328. } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
  329. /* Chosen more or less arbitrarily to have a nicer message,
  330. * otherwise all other return the same exit code 1. */
  331. if (!gdb_actual_connections)
  332. exit(1);
  333. else {
  334. fprintf(stderr,
  335. "semihosting: *** application exited with error ***\n");
  336. }
  337. } else {
  338. if (!gdb_actual_connections)
  339. exit(1);
  340. else {
  341. fprintf(stderr,
  342. "semihosting: application exception %#x\n",
  343. (unsigned) semihosting->param);
  344. }
  345. }
  346. }
  347. if (!semihosting->has_resumable_exit) {
  348. semihosting->is_resumable = false;
  349. return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  350. }
  351. break;
  352. case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
  353. /*
  354. * This operation is only supported if the semihosting extension
  355. * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
  356. * reported using feature byte 0, bit 0. If this extension is
  357. * supported, then the implementation provides a means to
  358. * report a normal exit with a nonzero exit status in both 32-bit
  359. * and 64-bit semihosting APIs.
  360. *
  361. * The implementation must provide the semihosting call
  362. * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
  363. *
  364. * SYS_EXIT_EXTENDED is used by an application to report an
  365. * exception or exit to the debugger directly. The most common
  366. * use is to report that execution has completed, using
  367. * ADP_Stopped_ApplicationExit.
  368. *
  369. * Entry
  370. * On entry, the PARAMETER REGISTER contains a pointer to a
  371. * two-field argument block:
  372. * - field 1 The exception type, which should be one of the set
  373. * of reason codes that are documented for the SYS_EXIT
  374. * (0x18) call. For example, ADP_Stopped_ApplicationExit.
  375. * - field 2 A subcode, whose meaning depends on the reason
  376. * code in field 1. In particular, if field 1 is
  377. * ADP_Stopped_ApplicationExit then field 2 is an exit status
  378. * code, as passed to the C standard library exit() function.
  379. * A simulator receiving this request must notify a connected
  380. * debugger, if present, and then exit with the specified status.
  381. *
  382. * Return
  383. * No return is expected from these calls.
  384. *
  385. * For the A64 API, this call is identical to the behavior of
  386. * the mandatory SYS_EXIT (0x18) call. If this extension is
  387. * supported, then both calls must be implemented.
  388. */
  389. retval = semihosting_read_fields(target, 2, fields);
  390. if (retval != ERROR_OK)
  391. return retval;
  392. else {
  393. int type = semihosting_get_field(target, 0, fields);
  394. int code = semihosting_get_field(target, 1, fields);
  395. if (type == ADP_STOPPED_APPLICATION_EXIT) {
  396. if (!gdb_actual_connections)
  397. exit(code);
  398. else {
  399. fprintf(stderr,
  400. "semihosting: *** application exited with %d ***\n",
  401. code);
  402. }
  403. } else {
  404. fprintf(stderr, "semihosting: exception %#x\n",
  405. type);
  406. }
  407. }
  408. if (!semihosting->has_resumable_exit) {
  409. semihosting->is_resumable = false;
  410. return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  411. }
  412. break;
  413. case SEMIHOSTING_SYS_FLEN: /* 0x0C */
  414. /*
  415. * Returns the length of a specified file.
  416. *
  417. * Entry
  418. * On entry, the PARAMETER REGISTER contains a pointer to a
  419. * one-field argument block:
  420. * - field 1 A handle for a previously opened, seekable file
  421. * object.
  422. *
  423. * Return
  424. * On exit, the RETURN REGISTER contains:
  425. * - The current length of the file object, if the call is
  426. * successful.
  427. * - –1 if an error occurs.
  428. */
  429. if (semihosting->is_fileio) {
  430. semihosting->result = -1;
  431. semihosting->sys_errno = EINVAL;
  432. }
  433. retval = semihosting_read_fields(target, 1, fields);
  434. if (retval != ERROR_OK)
  435. return retval;
  436. else {
  437. int fd = semihosting_get_field(target, 0, fields);
  438. struct stat buf;
  439. semihosting->result = fstat(fd, &buf);
  440. if (semihosting->result == -1) {
  441. semihosting->sys_errno = errno;
  442. LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
  443. break;
  444. }
  445. LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
  446. semihosting->result = buf.st_size;
  447. }
  448. break;
  449. case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
  450. /*
  451. * Returns the command line that is used for the call to the
  452. * executable, that is, argc and argv.
  453. *
  454. * Entry
  455. * On entry, the PARAMETER REGISTER points to a two-field data
  456. * block to be used for returning the command string and its length:
  457. * - field 1 A pointer to a buffer of at least the size that is
  458. * specified in field 2.
  459. * - field 2 The length of the buffer in bytes.
  460. *
  461. * Return
  462. * On exit:
  463. * If the call is successful, then the RETURN REGISTER contains 0,
  464. * the PARAMETER REGISTER is unchanged, and the data block is
  465. * updated as follows:
  466. * - field 1 A pointer to a null-terminated string of the command
  467. * line.
  468. * - field 2 The length of the string in bytes.
  469. * If the call is not successful, then the RETURN REGISTER
  470. * contains -1.
  471. *
  472. * Note: The semihosting implementation might impose limits on
  473. * the maximum length of the string that can be transferred.
  474. * However, the implementation must be able to support a
  475. * command-line length of at least 80 bytes.
  476. */
  477. retval = semihosting_read_fields(target, 2, fields);
  478. if (retval != ERROR_OK)
  479. return retval;
  480. else {
  481. uint64_t addr = semihosting_get_field(target, 0, fields);
  482. size_t size = semihosting_get_field(target, 1, fields);
  483. char *arg = semihosting->cmdline ?
  484. semihosting->cmdline : "";
  485. uint32_t len = strlen(arg) + 1;
  486. if (len > size)
  487. semihosting->result = -1;
  488. else {
  489. semihosting_set_field(target, len, 1, fields);
  490. retval = target_write_buffer(target, addr, len,
  491. (uint8_t *)arg);
  492. if (retval != ERROR_OK)
  493. return retval;
  494. semihosting->result = 0;
  495. retval = semihosting_write_fields(target, 2, fields);
  496. if (retval != ERROR_OK)
  497. return retval;
  498. }
  499. LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
  500. (int)semihosting->result);
  501. }
  502. break;
  503. case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
  504. /*
  505. * Returns the system stack and heap parameters.
  506. *
  507. * Entry
  508. * On entry, the PARAMETER REGISTER contains the address of a
  509. * pointer to a four-field data block. The contents of the data
  510. * block are filled by the function. The following C-like
  511. * pseudocode describes the layout of the block:
  512. * struct block {
  513. * void* heap_base;
  514. * void* heap_limit;
  515. * void* stack_base;
  516. * void* stack_limit;
  517. * };
  518. *
  519. * Return
  520. * On exit, the PARAMETER REGISTER is unchanged and the data
  521. * block has been updated.
  522. */
  523. retval = semihosting_read_fields(target, 1, fields);
  524. if (retval != ERROR_OK)
  525. return retval;
  526. else {
  527. uint64_t addr = semihosting_get_field(target, 0, fields);
  528. /* tell the remote we have no idea */
  529. memset(fields, 0, 4 * semihosting->word_size_bytes);
  530. retval = target_write_memory(target, addr, 4,
  531. semihosting->word_size_bytes,
  532. fields);
  533. if (retval != ERROR_OK)
  534. return retval;
  535. semihosting->result = 0;
  536. }
  537. break;
  538. case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
  539. /*
  540. * Determines whether the return code from another semihosting
  541. * call is an error status or not.
  542. *
  543. * This call is passed a parameter block containing the error
  544. * code to examine.
  545. *
  546. * Entry
  547. * On entry, the PARAMETER REGISTER contains a pointer to a
  548. * one-field data block:
  549. * - field 1 The required status word to check.
  550. *
  551. * Return
  552. * On exit, the RETURN REGISTER contains:
  553. * - 0 if the status field is not an error indication
  554. * - A nonzero value if the status field is an error indication.
  555. */
  556. retval = semihosting_read_fields(target, 1, fields);
  557. if (retval != ERROR_OK)
  558. return retval;
  559. uint64_t code = semihosting_get_field(target, 0, fields);
  560. semihosting->result = (code != 0);
  561. break;
  562. case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
  563. /*
  564. * Checks whether a file is connected to an interactive device.
  565. *
  566. * Entry
  567. * On entry, the PARAMETER REGISTER contains a pointer to a
  568. * one-field argument block:
  569. * field 1 A handle for a previously opened file object.
  570. *
  571. * Return
  572. * On exit, the RETURN REGISTER contains:
  573. * - 1 if the handle identifies an interactive device.
  574. * - 0 if the handle identifies a file.
  575. * - A value other than 1 or 0 if an error occurs.
  576. */
  577. if (semihosting->is_fileio) {
  578. semihosting->hit_fileio = true;
  579. fileio_info->identifier = "isatty";
  580. fileio_info->param_1 = semihosting->param;
  581. } else {
  582. retval = semihosting_read_fields(target, 1, fields);
  583. if (retval != ERROR_OK)
  584. return retval;
  585. int fd = semihosting_get_field(target, 0, fields);
  586. semihosting->result = isatty(fd);
  587. semihosting->sys_errno = errno;
  588. LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
  589. }
  590. break;
  591. case SEMIHOSTING_SYS_OPEN: /* 0x01 */
  592. /*
  593. * Opens a file on the host system.
  594. *
  595. * The file path is specified either as relative to the current
  596. * directory of the host process, or absolute, using the path
  597. * conventions of the host operating system.
  598. *
  599. * Semihosting implementations must support opening the special
  600. * path name :semihosting-features as part of the semihosting
  601. * extensions reporting mechanism.
  602. *
  603. * ARM targets interpret the special path name :tt as meaning
  604. * the console input stream, for an open-read or the console
  605. * output stream, for an open-write. Opening these streams is
  606. * performed as part of the standard startup code for those
  607. * applications that reference the C stdio streams. The
  608. * semihosting extension SH_EXT_STDOUT_STDERR allows the
  609. * semihosting caller to open separate output streams
  610. * corresponding to stdout and stderr. This extension is
  611. * reported using feature byte 0, bit 1. Use SYS_OPEN with
  612. * the special path name :semihosting-features to access the
  613. * feature bits.
  614. *
  615. * If this extension is supported, the implementation must
  616. * support the following additional semantics to SYS_OPEN:
  617. * - If the special path name :tt is opened with an fopen
  618. * mode requesting write access (w, wb, w+, or w+b), then
  619. * this is a request to open stdout.
  620. * - If the special path name :tt is opened with a mode
  621. * requesting append access (a, ab, a+, or a+b), then this is
  622. * a request to open stderr.
  623. *
  624. * Entry
  625. * On entry, the PARAMETER REGISTER contains a pointer to a
  626. * three-field argument block:
  627. * - field 1 A pointer to a null-terminated string containing
  628. * a file or device name.
  629. * - field 2 An integer that specifies the file opening mode.
  630. * - field 3 An integer that gives the length of the string
  631. * pointed to by field 1.
  632. *
  633. * The length does not include the terminating null character
  634. * that must be present.
  635. *
  636. * Return
  637. * On exit, the RETURN REGISTER contains:
  638. * - A nonzero handle if the call is successful.
  639. * - –1 if the call is not successful.
  640. */
  641. retval = semihosting_read_fields(target, 3, fields);
  642. if (retval != ERROR_OK)
  643. return retval;
  644. else {
  645. uint64_t addr = semihosting_get_field(target, 0, fields);
  646. uint32_t mode = semihosting_get_field(target, 1, fields);
  647. size_t len = semihosting_get_field(target, 2, fields);
  648. if (mode > 11) {
  649. semihosting->result = -1;
  650. semihosting->sys_errno = EINVAL;
  651. break;
  652. }
  653. uint8_t *fn = malloc(len+1);
  654. if (!fn) {
  655. semihosting->result = -1;
  656. semihosting->sys_errno = ENOMEM;
  657. } else {
  658. retval = target_read_memory(target, addr, 1, len, fn);
  659. if (retval != ERROR_OK) {
  660. free(fn);
  661. return retval;
  662. }
  663. fn[len] = 0;
  664. /* TODO: implement the :semihosting-features special file.
  665. * */
  666. if (semihosting->is_fileio) {
  667. if (strcmp((char *)fn, ":semihosting-features") == 0) {
  668. semihosting->result = -1;
  669. semihosting->sys_errno = EINVAL;
  670. } else if (strcmp((char *)fn, ":tt") == 0) {
  671. if (mode == 0)
  672. semihosting->result = 0;
  673. else if (mode == 4)
  674. semihosting->result = 1;
  675. else if (mode == 8)
  676. semihosting->result = 2;
  677. else
  678. semihosting->result = -1;
  679. } else {
  680. semihosting->hit_fileio = true;
  681. fileio_info->identifier = "open";
  682. fileio_info->param_1 = addr;
  683. fileio_info->param_2 = len;
  684. fileio_info->param_3 = open_modeflags[mode];
  685. fileio_info->param_4 = 0644;
  686. }
  687. } else {
  688. if (strcmp((char *)fn, ":tt") == 0) {
  689. /* Mode is:
  690. * - 0-3 ("r") for stdin,
  691. * - 4-7 ("w") for stdout,
  692. * - 8-11 ("a") for stderr */
  693. if (mode < 4) {
  694. semihosting->result = dup(
  695. STDIN_FILENO);
  696. semihosting->sys_errno = errno;
  697. LOG_DEBUG("dup(STDIN)=%d",
  698. (int)semihosting->result);
  699. } else if (mode < 8) {
  700. semihosting->result = dup(
  701. STDOUT_FILENO);
  702. semihosting->sys_errno = errno;
  703. LOG_DEBUG("dup(STDOUT)=%d",
  704. (int)semihosting->result);
  705. } else {
  706. semihosting->result = dup(
  707. STDERR_FILENO);
  708. semihosting->sys_errno = errno;
  709. LOG_DEBUG("dup(STDERR)=%d",
  710. (int)semihosting->result);
  711. }
  712. } else {
  713. /* cygwin requires the permission setting
  714. * otherwise it will fail to reopen a previously
  715. * written file */
  716. semihosting->result = open((char *)fn,
  717. open_modeflags[mode],
  718. 0644);
  719. semihosting->sys_errno = errno;
  720. LOG_DEBUG("open('%s')=%d", fn,
  721. (int)semihosting->result);
  722. }
  723. }
  724. free(fn);
  725. }
  726. }
  727. break;
  728. case SEMIHOSTING_SYS_READ: /* 0x06 */
  729. /*
  730. * Reads the contents of a file into a buffer. The file position
  731. * is specified either:
  732. * - Explicitly by a SYS_SEEK.
  733. * - Implicitly one byte beyond the previous SYS_READ or
  734. * SYS_WRITE request.
  735. *
  736. * The file position is at the start of the file when it is
  737. * opened, and is lost when the file is closed. Perform the
  738. * file operation as a single action whenever possible. For
  739. * example, do not split a read of 16KB into four 4KB chunks
  740. * unless there is no alternative.
  741. *
  742. * Entry
  743. * On entry, the PARAMETER REGISTER contains a pointer to a
  744. * three-field data block:
  745. * - field 1 Contains a handle for a file previously opened
  746. * with SYS_OPEN.
  747. * - field 2 Points to a buffer.
  748. * - field 3 Contains the number of bytes to read to the buffer
  749. * from the file.
  750. *
  751. * Return
  752. * On exit, the RETURN REGISTER contains the number of bytes not
  753. * filled in the buffer (buffer_length - bytes_read) as follows:
  754. * - If the RETURN REGISTER is 0, the entire buffer was
  755. * successfully filled.
  756. * - If the RETURN REGISTER is the same as field 3, no bytes
  757. * were read (EOF can be assumed).
  758. * - If the RETURN REGISTER contains a value smaller than
  759. * field 3, the read succeeded but the buffer was only partly
  760. * filled. For interactive devices, this is the most common
  761. * return value.
  762. */
  763. retval = semihosting_read_fields(target, 3, fields);
  764. if (retval != ERROR_OK)
  765. return retval;
  766. else {
  767. int fd = semihosting_get_field(target, 0, fields);
  768. uint64_t addr = semihosting_get_field(target, 1, fields);
  769. size_t len = semihosting_get_field(target, 2, fields);
  770. if (semihosting->is_fileio) {
  771. semihosting->hit_fileio = true;
  772. fileio_info->identifier = "read";
  773. fileio_info->param_1 = fd;
  774. fileio_info->param_2 = addr;
  775. fileio_info->param_3 = len;
  776. } else {
  777. uint8_t *buf = malloc(len);
  778. if (!buf) {
  779. semihosting->result = -1;
  780. semihosting->sys_errno = ENOMEM;
  781. } else {
  782. semihosting->result = read(fd, buf, len);
  783. semihosting->sys_errno = errno;
  784. LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
  785. fd,
  786. addr,
  787. len,
  788. (int)semihosting->result);
  789. if (semihosting->result >= 0) {
  790. retval = target_write_buffer(target, addr,
  791. semihosting->result,
  792. buf);
  793. if (retval != ERROR_OK) {
  794. free(buf);
  795. return retval;
  796. }
  797. /* the number of bytes NOT filled in */
  798. semihosting->result = len -
  799. semihosting->result;
  800. }
  801. free(buf);
  802. }
  803. }
  804. }
  805. break;
  806. case SEMIHOSTING_SYS_READC: /* 0x07 */
  807. /*
  808. * Reads a byte from the console.
  809. *
  810. * Entry
  811. * The PARAMETER REGISTER must contain 0. There are no other
  812. * parameters or values possible.
  813. *
  814. * Return
  815. * On exit, the RETURN REGISTER contains the byte read from
  816. * the console.
  817. */
  818. if (semihosting->is_fileio) {
  819. LOG_ERROR("SYS_READC not supported by semihosting fileio");
  820. return ERROR_FAIL;
  821. }
  822. semihosting->result = getchar();
  823. LOG_DEBUG("getchar()=%d", (int)semihosting->result);
  824. break;
  825. case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
  826. /*
  827. * Deletes a specified file on the host filing system.
  828. *
  829. * Entry
  830. * On entry, the PARAMETER REGISTER contains a pointer to a
  831. * two-field argument block:
  832. * - field 1 Points to a null-terminated string that gives the
  833. * path name of the file to be deleted.
  834. * - field 2 The length of the string.
  835. *
  836. * Return
  837. * On exit, the RETURN REGISTER contains:
  838. * - 0 if the delete is successful
  839. * - A nonzero, host-specific error code if the delete fails.
  840. */
  841. retval = semihosting_read_fields(target, 2, fields);
  842. if (retval != ERROR_OK)
  843. return retval;
  844. else {
  845. uint64_t addr = semihosting_get_field(target, 0, fields);
  846. size_t len = semihosting_get_field(target, 1, fields);
  847. if (semihosting->is_fileio) {
  848. semihosting->hit_fileio = true;
  849. fileio_info->identifier = "unlink";
  850. fileio_info->param_1 = addr;
  851. fileio_info->param_2 = len;
  852. } else {
  853. uint8_t *fn = malloc(len+1);
  854. if (!fn) {
  855. semihosting->result = -1;
  856. semihosting->sys_errno = ENOMEM;
  857. } else {
  858. retval =
  859. target_read_memory(target, addr, 1, len,
  860. fn);
  861. if (retval != ERROR_OK) {
  862. free(fn);
  863. return retval;
  864. }
  865. fn[len] = 0;
  866. semihosting->result = remove((char *)fn);
  867. semihosting->sys_errno = errno;
  868. LOG_DEBUG("remove('%s')=%d", fn,
  869. (int)semihosting->result);
  870. free(fn);
  871. }
  872. }
  873. }
  874. break;
  875. case SEMIHOSTING_SYS_RENAME: /* 0x0F */
  876. /*
  877. * Renames a specified file.
  878. *
  879. * Entry
  880. * On entry, the PARAMETER REGISTER contains a pointer to a
  881. * four-field data block:
  882. * - field 1 A pointer to the name of the old file.
  883. * - field 2 The length of the old filename.
  884. * - field 3 A pointer to the new filename.
  885. * - field 4 The length of the new filename. Both strings are
  886. * null-terminated.
  887. *
  888. * Return
  889. * On exit, the RETURN REGISTER contains:
  890. * - 0 if the rename is successful.
  891. * - A nonzero, host-specific error code if the rename fails.
  892. */
  893. retval = semihosting_read_fields(target, 4, fields);
  894. if (retval != ERROR_OK)
  895. return retval;
  896. else {
  897. uint64_t addr1 = semihosting_get_field(target, 0, fields);
  898. size_t len1 = semihosting_get_field(target, 1, fields);
  899. uint64_t addr2 = semihosting_get_field(target, 2, fields);
  900. size_t len2 = semihosting_get_field(target, 3, fields);
  901. if (semihosting->is_fileio) {
  902. semihosting->hit_fileio = true;
  903. fileio_info->identifier = "rename";
  904. fileio_info->param_1 = addr1;
  905. fileio_info->param_2 = len1;
  906. fileio_info->param_3 = addr2;
  907. fileio_info->param_4 = len2;
  908. } else {
  909. uint8_t *fn1 = malloc(len1+1);
  910. uint8_t *fn2 = malloc(len2+1);
  911. if (!fn1 || !fn2) {
  912. free(fn1);
  913. free(fn2);
  914. semihosting->result = -1;
  915. semihosting->sys_errno = ENOMEM;
  916. } else {
  917. retval = target_read_memory(target, addr1, 1, len1,
  918. fn1);
  919. if (retval != ERROR_OK) {
  920. free(fn1);
  921. free(fn2);
  922. return retval;
  923. }
  924. retval = target_read_memory(target, addr2, 1, len2,
  925. fn2);
  926. if (retval != ERROR_OK) {
  927. free(fn1);
  928. free(fn2);
  929. return retval;
  930. }
  931. fn1[len1] = 0;
  932. fn2[len2] = 0;
  933. semihosting->result = rename((char *)fn1,
  934. (char *)fn2);
  935. semihosting->sys_errno = errno;
  936. LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
  937. (int)semihosting->result);
  938. free(fn1);
  939. free(fn2);
  940. }
  941. }
  942. }
  943. break;
  944. case SEMIHOSTING_SYS_SEEK: /* 0x0A */
  945. /*
  946. * Seeks to a specified position in a file using an offset
  947. * specified from the start of the file. The file is assumed
  948. * to be a byte array and the offset is given in bytes.
  949. *
  950. * Entry
  951. * On entry, the PARAMETER REGISTER contains a pointer to a
  952. * two-field data block:
  953. * - field 1 A handle for a seekable file object.
  954. * - field 2 The absolute byte position to seek to.
  955. *
  956. * Return
  957. * On exit, the RETURN REGISTER contains:
  958. * - 0 if the request is successful.
  959. * - A negative value if the request is not successful.
  960. * Use SYS_ERRNO to read the value of the host errno variable
  961. * describing the error.
  962. *
  963. * Note: The effect of seeking outside the current extent of
  964. * the file object is undefined.
  965. */
  966. retval = semihosting_read_fields(target, 2, fields);
  967. if (retval != ERROR_OK)
  968. return retval;
  969. else {
  970. int fd = semihosting_get_field(target, 0, fields);
  971. off_t pos = semihosting_get_field(target, 1, fields);
  972. if (semihosting->is_fileio) {
  973. semihosting->hit_fileio = true;
  974. fileio_info->identifier = "lseek";
  975. fileio_info->param_1 = fd;
  976. fileio_info->param_2 = pos;
  977. fileio_info->param_3 = SEEK_SET;
  978. } else {
  979. semihosting->result = lseek(fd, pos, SEEK_SET);
  980. semihosting->sys_errno = errno;
  981. LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
  982. (int)semihosting->result);
  983. if (semihosting->result == pos)
  984. semihosting->result = 0;
  985. }
  986. }
  987. break;
  988. case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
  989. /*
  990. * Passes a command to the host command-line interpreter.
  991. * This enables you to execute a system command such as dir,
  992. * ls, or pwd. The terminal I/O is on the host, and is not
  993. * visible to the target.
  994. *
  995. * Entry
  996. * On entry, the PARAMETER REGISTER contains a pointer to a
  997. * two-field argument block:
  998. * - field 1 Points to a string to be passed to the host
  999. * command-line interpreter.
  1000. * - field 2 The length of the string.
  1001. *
  1002. * Return
  1003. * On exit, the RETURN REGISTER contains the return status.
  1004. */
  1005. /* Provide SYS_SYSTEM functionality. Uses the
  1006. * libc system command, there may be a reason *NOT*
  1007. * to use this, but as I can't think of one, I
  1008. * implemented it this way.
  1009. */
  1010. retval = semihosting_read_fields(target, 2, fields);
  1011. if (retval != ERROR_OK)
  1012. return retval;
  1013. else {
  1014. uint64_t addr = semihosting_get_field(target, 0, fields);
  1015. size_t len = semihosting_get_field(target, 1, fields);
  1016. if (semihosting->is_fileio) {
  1017. semihosting->hit_fileio = true;
  1018. fileio_info->identifier = "system";
  1019. fileio_info->param_1 = addr;
  1020. fileio_info->param_2 = len;
  1021. } else {
  1022. uint8_t *cmd = malloc(len+1);
  1023. if (!cmd) {
  1024. semihosting->result = -1;
  1025. semihosting->sys_errno = ENOMEM;
  1026. } else {
  1027. retval = target_read_memory(target,
  1028. addr,
  1029. 1,
  1030. len,
  1031. cmd);
  1032. if (retval != ERROR_OK) {
  1033. free(cmd);
  1034. return retval;
  1035. } else {
  1036. cmd[len] = 0;
  1037. semihosting->result = system(
  1038. (const char *)cmd);
  1039. LOG_DEBUG("system('%s')=%d",
  1040. cmd,
  1041. (int)semihosting->result);
  1042. }
  1043. free(cmd);
  1044. }
  1045. }
  1046. }
  1047. break;
  1048. case SEMIHOSTING_SYS_TIME: /* 0x11 */
  1049. /*
  1050. * Returns the number of seconds since 00:00 January 1, 1970.
  1051. * This value is real-world time, regardless of any debug agent
  1052. * configuration.
  1053. *
  1054. * Entry
  1055. * There are no parameters.
  1056. *
  1057. * Return
  1058. * On exit, the RETURN REGISTER contains the number of seconds.
  1059. */
  1060. semihosting->result = time(NULL);
  1061. break;
  1062. case SEMIHOSTING_SYS_WRITE: /* 0x05 */
  1063. /*
  1064. * Writes the contents of a buffer to a specified file at the
  1065. * current file position. The file position is specified either:
  1066. * - Explicitly, by a SYS_SEEK.
  1067. * - Implicitly as one byte beyond the previous SYS_READ or
  1068. * SYS_WRITE request.
  1069. *
  1070. * The file position is at the start of the file when the file
  1071. * is opened, and is lost when the file is closed.
  1072. *
  1073. * Perform the file operation as a single action whenever
  1074. * possible. For example, do not split a write of 16KB into
  1075. * four 4KB chunks unless there is no alternative.
  1076. *
  1077. * Entry
  1078. * On entry, the PARAMETER REGISTER contains a pointer to a
  1079. * three-field data block:
  1080. * - field 1 Contains a handle for a file previously opened
  1081. * with SYS_OPEN.
  1082. * - field 2 Points to the memory containing the data to be written.
  1083. * - field 3 Contains the number of bytes to be written from
  1084. * the buffer to the file.
  1085. *
  1086. * Return
  1087. * On exit, the RETURN REGISTER contains:
  1088. * - 0 if the call is successful.
  1089. * - The number of bytes that are not written, if there is an error.
  1090. */
  1091. retval = semihosting_read_fields(target, 3, fields);
  1092. if (retval != ERROR_OK)
  1093. return retval;
  1094. else {
  1095. int fd = semihosting_get_field(target, 0, fields);
  1096. uint64_t addr = semihosting_get_field(target, 1, fields);
  1097. size_t len = semihosting_get_field(target, 2, fields);
  1098. if (semihosting->is_fileio) {
  1099. semihosting->hit_fileio = true;
  1100. fileio_info->identifier = "write";
  1101. fileio_info->param_1 = fd;
  1102. fileio_info->param_2 = addr;
  1103. fileio_info->param_3 = len;
  1104. } else {
  1105. uint8_t *buf = malloc(len);
  1106. if (!buf) {
  1107. semihosting->result = -1;
  1108. semihosting->sys_errno = ENOMEM;
  1109. } else {
  1110. retval = target_read_buffer(target, addr, len, buf);
  1111. if (retval != ERROR_OK) {
  1112. free(buf);
  1113. return retval;
  1114. }
  1115. semihosting->result = write(fd, buf, len);
  1116. semihosting->sys_errno = errno;
  1117. LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
  1118. fd,
  1119. addr,
  1120. len,
  1121. (int)semihosting->result);
  1122. if (semihosting->result >= 0) {
  1123. /* The number of bytes that are NOT written.
  1124. * */
  1125. semihosting->result = len -
  1126. semihosting->result;
  1127. }
  1128. free(buf);
  1129. }
  1130. }
  1131. }
  1132. break;
  1133. case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
  1134. /*
  1135. * Writes a character byte, pointed to by the PARAMETER REGISTER,
  1136. * to the debug channel. When executed under a semihosting
  1137. * debugger, the character appears on the host debugger console.
  1138. *
  1139. * Entry
  1140. * On entry, the PARAMETER REGISTER contains a pointer to the
  1141. * character.
  1142. *
  1143. * Return
  1144. * None. The RETURN REGISTER is corrupted.
  1145. */
  1146. if (semihosting->is_fileio) {
  1147. semihosting->hit_fileio = true;
  1148. fileio_info->identifier = "write";
  1149. fileio_info->param_1 = 1;
  1150. fileio_info->param_2 = semihosting->param;
  1151. fileio_info->param_3 = 1;
  1152. } else {
  1153. uint64_t addr = semihosting->param;
  1154. unsigned char c;
  1155. retval = target_read_memory(target, addr, 1, 1, &c);
  1156. if (retval != ERROR_OK)
  1157. return retval;
  1158. putchar(c);
  1159. semihosting->result = 0;
  1160. }
  1161. break;
  1162. case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
  1163. /*
  1164. * Writes a null-terminated string to the debug channel.
  1165. * When executed under a semihosting debugger, the characters
  1166. * appear on the host debugger console.
  1167. *
  1168. * Entry
  1169. * On entry, the PARAMETER REGISTER contains a pointer to the
  1170. * first byte of the string.
  1171. *
  1172. * Return
  1173. * None. The RETURN REGISTER is corrupted.
  1174. */
  1175. if (semihosting->is_fileio) {
  1176. size_t count = 0;
  1177. uint64_t addr = semihosting->param;
  1178. for (;; addr++) {
  1179. unsigned char c;
  1180. retval = target_read_memory(target, addr, 1, 1, &c);
  1181. if (retval != ERROR_OK)
  1182. return retval;
  1183. if (c == '\0')
  1184. break;
  1185. count++;
  1186. }
  1187. semihosting->hit_fileio = true;
  1188. fileio_info->identifier = "write";
  1189. fileio_info->param_1 = 1;
  1190. fileio_info->param_2 = semihosting->param;
  1191. fileio_info->param_3 = count;
  1192. } else {
  1193. uint64_t addr = semihosting->param;
  1194. do {
  1195. unsigned char c;
  1196. retval = target_read_memory(target, addr++, 1, 1, &c);
  1197. if (retval != ERROR_OK)
  1198. return retval;
  1199. if (!c)
  1200. break;
  1201. putchar(c);
  1202. } while (1);
  1203. semihosting->result = 0;
  1204. }
  1205. break;
  1206. case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
  1207. /*
  1208. * Returns the number of elapsed target ticks since execution
  1209. * started.
  1210. * Use SYS_TICKFREQ to determine the tick frequency.
  1211. *
  1212. * Entry (32-bit)
  1213. * On entry, the PARAMETER REGISTER points to a two-field data
  1214. * block to be used for returning the number of elapsed ticks:
  1215. * - field 1 The least significant field and is at the low address.
  1216. * - field 2 The most significant field and is at the high address.
  1217. *
  1218. * Entry (64-bit)
  1219. * On entry the PARAMETER REGISTER points to a one-field data
  1220. * block to be used for returning the number of elapsed ticks:
  1221. * - field 1 The number of elapsed ticks as a 64-bit value.
  1222. *
  1223. * Return
  1224. * On exit:
  1225. * - On success, the RETURN REGISTER contains 0, the PARAMETER
  1226. * REGISTER is unchanged, and the data block pointed to by the
  1227. * PARAMETER REGISTER is filled in with the number of elapsed
  1228. * ticks.
  1229. * - On failure, the RETURN REGISTER contains -1, and the
  1230. * PARAMETER REGISTER contains -1.
  1231. *
  1232. * Note: Some semihosting implementations might not support this
  1233. * semihosting operation, and they always return -1 in the
  1234. * RETURN REGISTER.
  1235. */
  1236. case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
  1237. /*
  1238. * Returns the tick frequency.
  1239. *
  1240. * Entry
  1241. * The PARAMETER REGISTER must contain 0 on entry to this routine.
  1242. *
  1243. * Return
  1244. * On exit, the RETURN REGISTER contains either:
  1245. * - The number of ticks per second.
  1246. * - –1 if the target does not know the value of one tick.
  1247. *
  1248. * Note: Some semihosting implementations might not support
  1249. * this semihosting operation, and they always return -1 in the
  1250. * RETURN REGISTER.
  1251. */
  1252. case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
  1253. /*
  1254. * Returns a temporary name for a file identified by a system
  1255. * file identifier.
  1256. *
  1257. * Entry
  1258. * On entry, the PARAMETER REGISTER contains a pointer to a
  1259. * three-word argument block:
  1260. * - field 1 A pointer to a buffer.
  1261. * - field 2 A target identifier for this filename. Its value
  1262. * must be an integer in the range 0-255.
  1263. * - field 3 Contains the length of the buffer. The length must
  1264. * be at least the value of L_tmpnam on the host system.
  1265. *
  1266. * Return
  1267. * On exit, the RETURN REGISTER contains:
  1268. * - 0 if the call is successful.
  1269. * - –1 if an error occurs.
  1270. *
  1271. * The buffer pointed to by the PARAMETER REGISTER contains
  1272. * the filename, prefixed with a suitable directory name.
  1273. * If you use the same target identifier again, the same
  1274. * filename is returned.
  1275. *
  1276. * Note: The returned string must be null-terminated.
  1277. */
  1278. default:
  1279. fprintf(stderr, "semihosting: unsupported call %#x\n",
  1280. (unsigned) semihosting->op);
  1281. semihosting->result = -1;
  1282. semihosting->sys_errno = ENOTSUP;
  1283. }
  1284. if (!semihosting->hit_fileio) {
  1285. retval = semihosting->post_result(target);
  1286. if (retval != ERROR_OK) {
  1287. LOG_ERROR("Failed to post semihosting result");
  1288. return retval;
  1289. }
  1290. }
  1291. return ERROR_OK;
  1292. }
  1293. /* -------------------------------------------------------------------------
  1294. * Local functions. */
  1295. static int semihosting_common_fileio_info(struct target *target,
  1296. struct gdb_fileio_info *fileio_info)
  1297. {
  1298. struct semihosting *semihosting = target->semihosting;
  1299. if (!semihosting)
  1300. return ERROR_FAIL;
  1301. /*
  1302. * To avoid unnecessary duplication, semihosting prepares the
  1303. * fileio_info structure out-of-band when the target halts. See
  1304. * do_semihosting for more detail.
  1305. */
  1306. if (!semihosting->is_fileio || !semihosting->hit_fileio)
  1307. return ERROR_FAIL;
  1308. return ERROR_OK;
  1309. }
  1310. static int semihosting_common_fileio_end(struct target *target, int result,
  1311. int fileio_errno, bool ctrl_c)
  1312. {
  1313. struct gdb_fileio_info *fileio_info = target->fileio_info;
  1314. struct semihosting *semihosting = target->semihosting;
  1315. if (!semihosting)
  1316. return ERROR_FAIL;
  1317. /* clear pending status */
  1318. semihosting->hit_fileio = false;
  1319. semihosting->result = result;
  1320. semihosting->sys_errno = fileio_errno;
  1321. /*
  1322. * Some fileio results do not match up with what the semihosting
  1323. * operation expects; for these operations, we munge the results
  1324. * below:
  1325. */
  1326. switch (semihosting->op) {
  1327. case SEMIHOSTING_SYS_WRITE: /* 0x05 */
  1328. if (result < 0)
  1329. semihosting->result = fileio_info->param_3;
  1330. else
  1331. semihosting->result = 0;
  1332. break;
  1333. case SEMIHOSTING_SYS_READ: /* 0x06 */
  1334. if (result == (int)fileio_info->param_3)
  1335. semihosting->result = 0;
  1336. if (result <= 0)
  1337. semihosting->result = fileio_info->param_3;
  1338. break;
  1339. case SEMIHOSTING_SYS_SEEK: /* 0x0a */
  1340. if (result > 0)
  1341. semihosting->result = 0;
  1342. break;
  1343. }
  1344. return semihosting->post_result(target);
  1345. }
  1346. /**
  1347. * Read all fields of a command from target to buffer.
  1348. */
  1349. static int semihosting_read_fields(struct target *target, size_t number,
  1350. uint8_t *fields)
  1351. {
  1352. struct semihosting *semihosting = target->semihosting;
  1353. /* Use 4-byte multiples to trigger fast memory access. */
  1354. return target_read_memory(target, semihosting->param, 4,
  1355. number * (semihosting->word_size_bytes / 4), fields);
  1356. }
  1357. /**
  1358. * Write all fields of a command from buffer to target.
  1359. */
  1360. static int semihosting_write_fields(struct target *target, size_t number,
  1361. uint8_t *fields)
  1362. {
  1363. struct semihosting *semihosting = target->semihosting;
  1364. /* Use 4-byte multiples to trigger fast memory access. */
  1365. return target_write_memory(target, semihosting->param, 4,
  1366. number * (semihosting->word_size_bytes / 4), fields);
  1367. }
  1368. /**
  1369. * Extract a field from the buffer, considering register size and endianness.
  1370. */
  1371. static uint64_t semihosting_get_field(struct target *target, size_t index,
  1372. uint8_t *fields)
  1373. {
  1374. struct semihosting *semihosting = target->semihosting;
  1375. if (semihosting->word_size_bytes == 8)
  1376. return target_buffer_get_u64(target, fields + (index * 8));
  1377. else
  1378. return target_buffer_get_u32(target, fields + (index * 4));
  1379. }
  1380. /**
  1381. * Store a field in the buffer, considering register size and endianness.
  1382. */
  1383. static void semihosting_set_field(struct target *target, uint64_t value,
  1384. size_t index,
  1385. uint8_t *fields)
  1386. {
  1387. struct semihosting *semihosting = target->semihosting;
  1388. if (semihosting->word_size_bytes == 8)
  1389. target_buffer_set_u64(target, fields + (index * 8), value);
  1390. else
  1391. target_buffer_set_u32(target, fields + (index * 4), value);
  1392. }
  1393. /* -------------------------------------------------------------------------
  1394. * Common semihosting commands handlers. */
  1395. static __COMMAND_HANDLER(handle_common_semihosting_command)
  1396. {
  1397. struct target *target = get_current_target(CMD_CTX);
  1398. if (!target) {
  1399. LOG_ERROR("No target selected");
  1400. return ERROR_FAIL;
  1401. }
  1402. struct semihosting *semihosting = target->semihosting;
  1403. if (!semihosting) {
  1404. command_print(CMD, "semihosting not supported for current target");
  1405. return ERROR_FAIL;
  1406. }
  1407. if (CMD_ARGC > 0) {
  1408. int is_active;
  1409. COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
  1410. if (!target_was_examined(target)) {
  1411. LOG_ERROR("Target not examined yet");
  1412. return ERROR_FAIL;
  1413. }
  1414. if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
  1415. LOG_ERROR("Failed to Configure semihosting");
  1416. return ERROR_FAIL;
  1417. }
  1418. /* FIXME never let that "catch" be dropped! (???) */
  1419. semihosting->is_active = is_active;
  1420. }
  1421. command_print(CMD, "semihosting is %s",
  1422. semihosting->is_active
  1423. ? "enabled" : "disabled");
  1424. return ERROR_OK;
  1425. }
  1426. static __COMMAND_HANDLER(handle_common_semihosting_fileio_command)
  1427. {
  1428. struct target *target = get_current_target(CMD_CTX);
  1429. if (!target) {
  1430. LOG_ERROR("No target selected");
  1431. return ERROR_FAIL;
  1432. }
  1433. struct semihosting *semihosting = target->semihosting;
  1434. if (!semihosting) {
  1435. command_print(CMD, "semihosting not supported for current target");
  1436. return ERROR_FAIL;
  1437. }
  1438. if (!semihosting->is_active) {
  1439. command_print(CMD, "semihosting not yet enabled for current target");
  1440. return ERROR_FAIL;
  1441. }
  1442. if (CMD_ARGC > 0)
  1443. COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
  1444. command_print(CMD, "semihosting fileio is %s",
  1445. semihosting->is_fileio
  1446. ? "enabled" : "disabled");
  1447. return ERROR_OK;
  1448. }
  1449. static __COMMAND_HANDLER(handle_common_semihosting_cmdline)
  1450. {
  1451. struct target *target = get_current_target(CMD_CTX);
  1452. unsigned int i;
  1453. if (!target) {
  1454. LOG_ERROR("No target selected");
  1455. return ERROR_FAIL;
  1456. }
  1457. struct semihosting *semihosting = target->semihosting;
  1458. if (!semihosting) {
  1459. command_print(CMD, "semihosting not supported for current target");
  1460. return ERROR_FAIL;
  1461. }
  1462. free(semihosting->cmdline);
  1463. semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
  1464. for (i = 1; i < CMD_ARGC; i++) {
  1465. char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
  1466. if (!cmdline)
  1467. break;
  1468. free(semihosting->cmdline);
  1469. semihosting->cmdline = cmdline;
  1470. }
  1471. command_print(CMD, "semihosting command line is [%s]",
  1472. semihosting->cmdline);
  1473. return ERROR_OK;
  1474. }
  1475. static __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
  1476. {
  1477. struct target *target = get_current_target(CMD_CTX);
  1478. if (!target) {
  1479. LOG_ERROR("No target selected");
  1480. return ERROR_FAIL;
  1481. }
  1482. struct semihosting *semihosting = target->semihosting;
  1483. if (!semihosting) {
  1484. command_print(CMD, "semihosting not supported for current target");
  1485. return ERROR_FAIL;
  1486. }
  1487. if (!semihosting->is_active) {
  1488. command_print(CMD, "semihosting not yet enabled for current target");
  1489. return ERROR_FAIL;
  1490. }
  1491. if (CMD_ARGC > 0)
  1492. COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
  1493. command_print(CMD, "semihosting resumable exit is %s",
  1494. semihosting->has_resumable_exit
  1495. ? "enabled" : "disabled");
  1496. return ERROR_OK;
  1497. }
  1498. const struct command_registration semihosting_common_handlers[] = {
  1499. {
  1500. "semihosting",
  1501. .handler = handle_common_semihosting_command,
  1502. .mode = COMMAND_EXEC,
  1503. .usage = "['enable'|'disable']",
  1504. .help = "activate support for semihosting operations",
  1505. },
  1506. {
  1507. "semihosting_cmdline",
  1508. .handler = handle_common_semihosting_cmdline,
  1509. .mode = COMMAND_EXEC,
  1510. .usage = "arguments",
  1511. .help = "command line arguments to be passed to program",
  1512. },
  1513. {
  1514. "semihosting_fileio",
  1515. .handler = handle_common_semihosting_fileio_command,
  1516. .mode = COMMAND_EXEC,
  1517. .usage = "['enable'|'disable']",
  1518. .help = "activate support for semihosting fileio operations",
  1519. },
  1520. {
  1521. "semihosting_resexit",
  1522. .handler = handle_common_semihosting_resumable_exit_command,
  1523. .mode = COMMAND_EXEC,
  1524. .usage = "['enable'|'disable']",
  1525. .help = "activate support for semihosting resumable exit",
  1526. },
  1527. COMMAND_REGISTRATION_DONE
  1528. };