1 /***************************************************************************
2 * Copyright (C) 2018 by Liviu Ionescu *
5 * Copyright (C) 2018 by Marvell Technology Group Ltd. *
6 * Written by Nicolas Pitre <nico@marvell.com> *
8 * Copyright (C) 2010 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2016 by Square, Inc. *
12 * Steven Stallion <stallion@squareup.com> *
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. *
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. *
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 ***************************************************************************/
30 * Common ARM semihosting support.
32 * Semihosting enables code running on a target to use some of the I/O
33 * facilities on the host computer. The target application must be linked
34 * against a library that forwards operation requests by using an
35 * instruction trapped by the debugger.
37 * Details can be found in
38 * "Semihosting for AArch32 and AArch64, Release 2.0"
39 * https://static.docs.arm.com/100863/0200/semihosting.pdf
48 #include "target_type.h"
49 #include "semihosting_common.h"
51 #include <helper/binarybuffer.h>
52 #include <helper/log.h>
55 static const int open_modeflags[12] = {
60 O_WRONLY | O_CREAT | O_TRUNC,
61 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
62 O_RDWR | O_CREAT | O_TRUNC,
63 O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
64 O_WRONLY | O_CREAT | O_APPEND,
65 O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
66 O_RDWR | O_CREAT | O_APPEND,
67 O_RDWR | O_CREAT | O_APPEND | O_BINARY
70 static int semihosting_common_fileio_info(struct target *target,
71 struct gdb_fileio_info *fileio_info);
72 static int semihosting_common_fileio_end(struct target *target, int result,
73 int fileio_errno, bool ctrl_c);
75 static int semihosting_read_fields(struct target *target, size_t number,
77 static int semihosting_write_fields(struct target *target, size_t number,
79 static uint64_t semihosting_get_field(struct target *target, size_t index,
81 static void semihosting_set_field(struct target *target, uint64_t value,
85 /* Attempts to include gdb_server.h failed. */
86 extern int gdb_actual_connections;
89 * Initialize common semihosting support.
91 * @param target Pointer to the target to initialize.
92 * @return An error status if there is a problem during initialization.
94 int semihosting_common_init(struct target *target, void *setup,
99 target->fileio_info = malloc(sizeof(*target->fileio_info));
100 if (target->fileio_info == NULL) {
101 LOG_ERROR("out of memory");
104 memset(target->fileio_info, 0, sizeof(*target->fileio_info));
106 struct semihosting *semihosting;
107 semihosting = malloc(sizeof(*target->semihosting));
108 if (semihosting == NULL) {
109 LOG_ERROR("out of memory");
113 semihosting->is_active = false;
114 semihosting->is_fileio = false;
115 semihosting->hit_fileio = false;
116 semihosting->is_resumable = false;
117 semihosting->has_resumable_exit = false;
118 semihosting->word_size_bytes = 0;
119 semihosting->op = -1;
120 semihosting->param = 0;
121 semihosting->result = -1;
122 semihosting->sys_errno = -1;
123 semihosting->cmdline = NULL;
125 /* If possible, update it in setup(). */
126 semihosting->setup_time = clock();
128 semihosting->setup = setup;
129 semihosting->post_result = post_result;
131 target->semihosting = semihosting;
133 target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
134 target->type->gdb_fileio_end = semihosting_common_fileio_end;
140 * Portable implementation of ARM semihosting calls.
141 * Performs the currently pending semihosting operation
142 * encoded in target->semihosting.
144 int semihosting_common(struct target *target)
146 struct semihosting *semihosting = target->semihosting;
148 /* Silently ignore if the semhosting field was not set. */
152 struct gdb_fileio_info *fileio_info = target->fileio_info;
155 * By default return an error.
156 * The actual result must be set by each function
158 semihosting->result = -1;
160 /* Most operations are resumable, except the two exit calls. */
161 semihosting->is_resumable = true;
165 /* Enough space to hold 4 long words. */
168 LOG_DEBUG("op=0x%x, param=0x%" PRIx64, (int)semihosting->op,
171 switch (semihosting->op) {
173 case SEMIHOSTING_SYS_CLOCK: /* 0x10 */
175 * Returns the number of centiseconds (hundredths of a second)
176 * since the execution started.
178 * Values returned can be of limited use for some benchmarking
179 * purposes because of communication overhead or other
180 * agent-specific factors. For example, with a debug hardware
181 * unit the request is passed back to the host for execution.
182 * This can lead to unpredictable delays in transmission and
183 * process scheduling.
185 * Use this function to calculate time intervals, by calculating
186 * differences between intervals with and without the code
187 * sequence to be timed.
190 * The PARAMETER REGISTER must contain 0. There are no other
194 * On exit, the RETURN REGISTER contains:
195 * - The number of centiseconds since some arbitrary start
196 * point, if the call is successful.
197 * - –1 if the call is not successful. For example, because
198 * of a communications error.
201 clock_t delta = clock() - semihosting->setup_time;
203 semihosting->result = delta / (CLOCKS_PER_SEC / 100);
207 case SEMIHOSTING_SYS_CLOSE: /* 0x02 */
209 * Closes a file on the host system. The handle must reference
210 * a file that was opened with SYS_OPEN.
213 * On entry, the PARAMETER REGISTER contains a pointer to a
214 * one-field argument block:
215 * - field 1 Contains a handle for an open file.
218 * On exit, the RETURN REGISTER contains:
219 * - 0 if the call is successful
220 * - –1 if the call is not successful.
222 retval = semihosting_read_fields(target, 1, fields);
223 if (retval != ERROR_OK)
226 int fd = semihosting_get_field(target, 0, fields);
227 if (semihosting->is_fileio) {
228 if (fd == 0 || fd == 1 || fd == 2) {
229 semihosting->result = 0;
232 semihosting->hit_fileio = true;
233 fileio_info->identifier = "close";
234 fileio_info->param_1 = fd;
236 semihosting->result = close(fd);
237 semihosting->sys_errno = errno;
239 LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
244 case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
246 * Returns the value of the C library errno variable that is
247 * associated with the semihosting implementation. The errno
248 * variable can be set by a number of C library semihosted
249 * functions, including:
257 * Whether errno is set or not, and to what value, is entirely
258 * host-specific, except where the ISO C standard defines the
262 * There are no parameters. The PARAMETER REGISTER must be 0.
265 * On exit, the RETURN REGISTER contains the value of the C
266 * library errno variable.
268 semihosting->result = semihosting->sys_errno;
271 case SEMIHOSTING_SYS_EXIT: /* 0x18 */
273 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
274 * previous versions of the documentation.
276 * An application calls this operation to report an exception
277 * to the debugger directly. The most common use is to report
278 * that execution has completed, using ADP_Stopped_ApplicationExit.
280 * Note: This semihosting operation provides no means for 32-bit
281 * callers to indicate an application exit with a specified exit
282 * code. Semihosting callers may prefer to check for the presence
283 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
284 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
288 * On entry, the PARAMETER register is set to a reason code
289 * describing the cause of the trap. Not all semihosting client
290 * implementations will necessarily trap every corresponding
291 * event. Important reason codes are:
293 * - ADP_Stopped_ApplicationExit 0x20026
294 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
297 * On entry, the PARAMETER REGISTER contains a pointer to a
298 * two-field argument block:
299 * - field 1 The exception type, which is one of the set of
300 * reason codes in the above tables.
301 * - field 2 A subcode, whose meaning depends on the reason
303 * In particular, if field 1 is ADP_Stopped_ApplicationExit
304 * then field 2 is an exit status code, as passed to the C
305 * standard library exit() function. A simulator receiving
306 * this request must notify a connected debugger, if present,
307 * and then exit with the specified status.
310 * No return is expected from these calls. However, it is
311 * possible for the debugger to request that the application
312 * continues by performing an RDI_Execute request or equivalent.
313 * In this case, execution continues with the registers as they
314 * were on entry to the operation, or as subsequently modified
317 if (semihosting->word_size_bytes == 8) {
318 retval = semihosting_read_fields(target, 2, fields);
319 if (retval != ERROR_OK)
322 int type = semihosting_get_field(target, 0, fields);
323 int code = semihosting_get_field(target, 1, fields);
325 if (type == ADP_STOPPED_APPLICATION_EXIT) {
326 if (!gdb_actual_connections)
330 "semihosting: *** application exited with %d ***\n",
335 "semihosting: application exception %#x\n",
340 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
341 if (!gdb_actual_connections)
345 "semihosting: *** application exited normally ***\n");
347 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
348 /* Chosen more or less arbitrarly to have a nicer message,
349 * otherwise all other return the same exit code 1. */
350 if (!gdb_actual_connections)
354 "semihosting: *** application exited with error ***\n");
357 if (!gdb_actual_connections)
361 "semihosting: application exception %#x\n",
362 (unsigned) semihosting->param);
366 if (!semihosting->has_resumable_exit) {
367 semihosting->is_resumable = false;
368 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
372 case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
374 * This operation is only supported if the semihosting extension
375 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
376 * reported using feature byte 0, bit 0. If this extension is
377 * supported, then the implementation provides a means to
378 * report a normal exit with a nonzero exit status in both 32-bit
379 * and 64-bit semihosting APIs.
381 * The implementation must provide the semihosting call
382 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
384 * SYS_EXIT_EXTENDED is used by an application to report an
385 * exception or exit to the debugger directly. The most common
386 * use is to report that execution has completed, using
387 * ADP_Stopped_ApplicationExit.
390 * On entry, the PARAMETER REGISTER contains a pointer to a
391 * two-field argument block:
392 * - field 1 The exception type, which should be one of the set
393 * of reason codes that are documented for the SYS_EXIT
394 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
395 * - field 2 A subcode, whose meaning depends on the reason
396 * code in field 1. In particular, if field 1 is
397 * ADP_Stopped_ApplicationExit then field 2 is an exit status
398 * code, as passed to the C standard library exit() function.
399 * A simulator receiving this request must notify a connected
400 * debugger, if present, and then exit with the specified status.
403 * No return is expected from these calls.
405 * For the A64 API, this call is identical to the behavior of
406 * the mandatory SYS_EXIT (0x18) call. If this extension is
407 * supported, then both calls must be implemented.
409 retval = semihosting_read_fields(target, 2, fields);
410 if (retval != ERROR_OK)
413 int type = semihosting_get_field(target, 0, fields);
414 int code = semihosting_get_field(target, 1, fields);
416 if (type == ADP_STOPPED_APPLICATION_EXIT) {
417 if (!gdb_actual_connections)
421 "semihosting: *** application exited with %d ***\n",
425 fprintf(stderr, "semihosting: exception %#x\n",
429 if (!semihosting->has_resumable_exit) {
430 semihosting->is_resumable = false;
431 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
435 case SEMIHOSTING_SYS_FLEN: /* 0x0C */
437 * Returns the length of a specified file.
440 * On entry, the PARAMETER REGISTER contains a pointer to a
441 * one-field argument block:
442 * - field 1 A handle for a previously opened, seekable file
446 * On exit, the RETURN REGISTER contains:
447 * - The current length of the file object, if the call is
449 * - –1 if an error occurs.
451 if (semihosting->is_fileio) {
452 semihosting->result = -1;
453 semihosting->sys_errno = EINVAL;
455 retval = semihosting_read_fields(target, 1, fields);
456 if (retval != ERROR_OK)
459 int fd = semihosting_get_field(target, 0, fields);
461 semihosting->result = fstat(fd, &buf);
462 if (semihosting->result == -1) {
463 semihosting->sys_errno = errno;
464 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
467 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
468 semihosting->result = buf.st_size;
472 case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
474 * Returns the command line that is used for the call to the
475 * executable, that is, argc and argv.
478 * On entry, the PARAMETER REGISTER points to a two-field data
479 * block to be used for returning the command string and its length:
480 * - field 1 A pointer to a buffer of at least the size that is
481 * specified in field 2.
482 * - field 2 The length of the buffer in bytes.
486 * If the call is successful, then the RETURN REGISTER contains 0,
487 * the PARAMETER REGISTER is unchanged, and the data block is
488 * updated as follows:
489 * - field 1 A pointer to a null-terminated string of the command
491 * - field 2 The length of the string in bytes.
492 * If the call is not successful, then the RETURN REGISTER
495 * Note: The semihosting implementation might impose limits on
496 * the maximum length of the string that can be transferred.
497 * However, the implementation must be able to support a
498 * command-line length of at least 80 bytes.
500 retval = semihosting_read_fields(target, 2, fields);
501 if (retval != ERROR_OK)
504 uint64_t addr = semihosting_get_field(target, 0, fields);
505 size_t size = semihosting_get_field(target, 1, fields);
507 char *arg = semihosting->cmdline != NULL ?
508 semihosting->cmdline : "";
509 uint32_t len = strlen(arg) + 1;
511 semihosting->result = -1;
513 semihosting_set_field(target, len, 1, fields);
514 retval = target_write_buffer(target, addr, len,
516 if (retval != ERROR_OK)
518 semihosting->result = 0;
520 retval = semihosting_write_fields(target, 2, fields);
521 if (retval != ERROR_OK)
524 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
525 (int)semihosting->result);
529 case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
531 * Returns the system stack and heap parameters.
534 * On entry, the PARAMETER REGISTER contains the address of a
535 * pointer to a four-field data block. The contents of the data
536 * block are filled by the function. The following C-like
537 * pseudocode describes the layout of the block:
546 * On exit, the PARAMETER REGISTER is unchanged and the data
547 * block has been updated.
549 retval = semihosting_read_fields(target, 1, fields);
550 if (retval != ERROR_OK)
553 uint64_t addr = semihosting_get_field(target, 0, fields);
554 /* tell the remote we have no idea */
555 memset(fields, 0, 4 * semihosting->word_size_bytes);
556 retval = target_write_memory(target, addr, 4,
557 semihosting->word_size_bytes,
559 if (retval != ERROR_OK)
561 semihosting->result = 0;
565 case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
567 * Determines whether the return code from another semihosting
568 * call is an error status or not.
570 * This call is passed a parameter block containing the error
574 * On entry, the PARAMETER REGISTER contains a pointer to a
575 * one-field data block:
576 * - field 1 The required status word to check.
579 * On exit, the RETURN REGISTER contains:
580 * - 0 if the status field is not an error indication
581 * - A nonzero value if the status field is an error indication.
583 retval = semihosting_read_fields(target, 1, fields);
584 if (retval != ERROR_OK)
587 uint64_t code = semihosting_get_field(target, 0, fields);
588 semihosting->result = (code != 0);
591 case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
593 * Checks whether a file is connected to an interactive device.
596 * On entry, the PARAMETER REGISTER contains a pointer to a
597 * one-field argument block:
598 * field 1 A handle for a previously opened file object.
601 * On exit, the RETURN REGISTER contains:
602 * - 1 if the handle identifies an interactive device.
603 * - 0 if the handle identifies a file.
604 * - A value other than 1 or 0 if an error occurs.
606 if (semihosting->is_fileio) {
607 semihosting->hit_fileio = true;
608 fileio_info->identifier = "isatty";
609 fileio_info->param_1 = semihosting->param;
611 retval = semihosting_read_fields(target, 1, fields);
612 if (retval != ERROR_OK)
614 int fd = semihosting_get_field(target, 0, fields);
615 semihosting->result = isatty(fd);
616 LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
620 case SEMIHOSTING_SYS_OPEN: /* 0x01 */
622 * Opens a file on the host system.
624 * The file path is specified either as relative to the current
625 * directory of the host process, or absolute, using the path
626 * conventions of the host operating system.
628 * Semihosting implementations must support opening the special
629 * path name :semihosting-features as part of the semihosting
630 * extensions reporting mechanism.
632 * ARM targets interpret the special path name :tt as meaning
633 * the console input stream, for an open-read or the console
634 * output stream, for an open-write. Opening these streams is
635 * performed as part of the standard startup code for those
636 * applications that reference the C stdio streams. The
637 * semihosting extension SH_EXT_STDOUT_STDERR allows the
638 * semihosting caller to open separate output streams
639 * corresponding to stdout and stderr. This extension is
640 * reported using feature byte 0, bit 1. Use SYS_OPEN with
641 * the special path name :semihosting-features to access the
644 * If this extension is supported, the implementation must
645 * support the following additional semantics to SYS_OPEN:
646 * - If the special path name :tt is opened with an fopen
647 * mode requesting write access (w, wb, w+, or w+b), then
648 * this is a request to open stdout.
649 * - If the special path name :tt is opened with a mode
650 * requesting append access (a, ab, a+, or a+b), then this is
651 * a request to open stderr.
654 * On entry, the PARAMETER REGISTER contains a pointer to a
655 * three-field argument block:
656 * - field 1 A pointer to a null-terminated string containing
657 * a file or device name.
658 * - field 2 An integer that specifies the file opening mode.
659 * - field 3 An integer that gives the length of the string
660 * pointed to by field 1.
662 * The length does not include the terminating null character
663 * that must be present.
666 * On exit, the RETURN REGISTER contains:
667 * - A nonzero handle if the call is successful.
668 * - –1 if the call is not successful.
670 retval = semihosting_read_fields(target, 3, fields);
671 if (retval != ERROR_OK)
674 uint64_t addr = semihosting_get_field(target, 0, fields);
675 uint32_t mode = semihosting_get_field(target, 1, fields);
676 size_t len = semihosting_get_field(target, 2, fields);
679 semihosting->result = -1;
680 semihosting->sys_errno = EINVAL;
683 uint8_t *fn = malloc(len+1);
685 semihosting->result = -1;
686 semihosting->sys_errno = ENOMEM;
688 retval = target_read_memory(target, addr, 1, len, fn);
689 if (retval != ERROR_OK) {
694 /* TODO: implement the :semihosting-features special file.
696 if (semihosting->is_fileio) {
697 if (strcmp((char *)fn, ":semihosting-features") == 0) {
698 semihosting->result = -1;
699 semihosting->sys_errno = EINVAL;
700 } else if (strcmp((char *)fn, ":tt") == 0) {
702 semihosting->result = 0;
704 semihosting->result = 1;
706 semihosting->result = 2;
708 semihosting->result = -1;
710 semihosting->hit_fileio = true;
711 fileio_info->identifier = "open";
712 fileio_info->param_1 = addr;
713 fileio_info->param_2 = len;
714 fileio_info->param_3 = open_modeflags[mode];
715 fileio_info->param_4 = 0644;
718 if (strcmp((char *)fn, ":tt") == 0) {
720 * - 0-3 ("r") for stdin,
721 * - 4-7 ("w") for stdout,
722 * - 8-11 ("a") for stderr */
724 semihosting->result = dup(
726 semihosting->sys_errno = errno;
727 LOG_DEBUG("dup(STDIN)=%d",
728 (int)semihosting->result);
729 } else if (mode < 8) {
730 semihosting->result = dup(
732 semihosting->sys_errno = errno;
733 LOG_DEBUG("dup(STDOUT)=%d",
734 (int)semihosting->result);
736 semihosting->result = dup(
738 semihosting->sys_errno = errno;
739 LOG_DEBUG("dup(STDERR)=%d",
740 (int)semihosting->result);
743 /* cygwin requires the permission setting
744 * otherwise it will fail to reopen a previously
746 semihosting->result = open((char *)fn,
747 open_modeflags[mode],
749 semihosting->sys_errno = errno;
750 LOG_DEBUG("open('%s')=%d", fn,
751 (int)semihosting->result);
759 case SEMIHOSTING_SYS_READ: /* 0x06 */
761 * Reads the contents of a file into a buffer. The file position
762 * is specified either:
763 * - Explicitly by a SYS_SEEK.
764 * - Implicitly one byte beyond the previous SYS_READ or
767 * The file position is at the start of the file when it is
768 * opened, and is lost when the file is closed. Perform the
769 * file operation as a single action whenever possible. For
770 * example, do not split a read of 16KB into four 4KB chunks
771 * unless there is no alternative.
774 * On entry, the PARAMETER REGISTER contains a pointer to a
775 * three-field data block:
776 * - field 1 Contains a handle for a file previously opened
778 * - field 2 Points to a buffer.
779 * - field 3 Contains the number of bytes to read to the buffer
783 * On exit, the RETURN REGISTER contains the number of bytes not
784 * filled in the buffer (buffer_length - bytes_read) as follows:
785 * - If the RETURN REGISTER is 0, the entire buffer was
786 * successfully filled.
787 * - If the RETURN REGISTER is the same as field 3, no bytes
788 * were read (EOF can be assumed).
789 * - If the RETURN REGISTER contains a value smaller than
790 * field 3, the read succeeded but the buffer was only partly
791 * filled. For interactive devices, this is the most common
794 retval = semihosting_read_fields(target, 3, fields);
795 if (retval != ERROR_OK)
798 int fd = semihosting_get_field(target, 0, fields);
799 uint64_t addr = semihosting_get_field(target, 1, fields);
800 size_t len = semihosting_get_field(target, 2, fields);
801 if (semihosting->is_fileio) {
802 semihosting->hit_fileio = true;
803 fileio_info->identifier = "read";
804 fileio_info->param_1 = fd;
805 fileio_info->param_2 = addr;
806 fileio_info->param_3 = len;
808 uint8_t *buf = malloc(len);
810 semihosting->result = -1;
811 semihosting->sys_errno = ENOMEM;
813 semihosting->result = read(fd, buf, len);
814 semihosting->sys_errno = errno;
815 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
819 (int)semihosting->result);
820 if (semihosting->result >= 0) {
821 retval = target_write_buffer(target, addr,
824 if (retval != ERROR_OK) {
828 /* the number of bytes NOT filled in */
829 semihosting->result = len -
838 case SEMIHOSTING_SYS_READC: /* 0x07 */
840 * Reads a byte from the console.
843 * The PARAMETER REGISTER must contain 0. There are no other
844 * parameters or values possible.
847 * On exit, the RETURN REGISTER contains the byte read from
850 if (semihosting->is_fileio) {
851 LOG_ERROR("SYS_READC not supported by semihosting fileio");
854 semihosting->result = getchar();
855 LOG_DEBUG("getchar()=%d", (int)semihosting->result);
858 case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
860 * Deletes a specified file on the host filing system.
863 * On entry, the PARAMETER REGISTER contains a pointer to a
864 * two-field argument block:
865 * - field 1 Points to a null-terminated string that gives the
866 * path name of the file to be deleted.
867 * - field 2 The length of the string.
870 * On exit, the RETURN REGISTER contains:
871 * - 0 if the delete is successful
872 * - A nonzero, host-specific error code if the delete fails.
874 retval = semihosting_read_fields(target, 2, fields);
875 if (retval != ERROR_OK)
878 uint64_t addr = semihosting_get_field(target, 0, fields);
879 size_t len = semihosting_get_field(target, 1, fields);
880 if (semihosting->is_fileio) {
881 semihosting->hit_fileio = true;
882 fileio_info->identifier = "unlink";
883 fileio_info->param_1 = addr;
884 fileio_info->param_2 = len;
886 uint8_t *fn = malloc(len+1);
888 semihosting->result = -1;
889 semihosting->sys_errno = ENOMEM;
892 target_read_memory(target, addr, 1, len,
894 if (retval != ERROR_OK) {
899 semihosting->result = remove((char *)fn);
900 semihosting->sys_errno = errno;
901 LOG_DEBUG("remove('%s')=%d", fn,
902 (int)semihosting->result);
910 case SEMIHOSTING_SYS_RENAME: /* 0x0F */
912 * Renames a specified file.
915 * On entry, the PARAMETER REGISTER contains a pointer to a
916 * four-field data block:
917 * - field 1 A pointer to the name of the old file.
918 * - field 2 The length of the old filename.
919 * - field 3 A pointer to the new filename.
920 * - field 4 The length of the new filename. Both strings are
924 * On exit, the RETURN REGISTER contains:
925 * - 0 if the rename is successful.
926 * - A nonzero, host-specific error code if the rename fails.
928 retval = semihosting_read_fields(target, 4, fields);
929 if (retval != ERROR_OK)
932 uint64_t addr1 = semihosting_get_field(target, 0, fields);
933 size_t len1 = semihosting_get_field(target, 1, fields);
934 uint64_t addr2 = semihosting_get_field(target, 2, fields);
935 size_t len2 = semihosting_get_field(target, 3, fields);
936 if (semihosting->is_fileio) {
937 semihosting->hit_fileio = true;
938 fileio_info->identifier = "rename";
939 fileio_info->param_1 = addr1;
940 fileio_info->param_2 = len1;
941 fileio_info->param_3 = addr2;
942 fileio_info->param_4 = len2;
944 uint8_t *fn1 = malloc(len1+1);
945 uint8_t *fn2 = malloc(len2+1);
947 semihosting->result = -1;
948 semihosting->sys_errno = ENOMEM;
950 retval = target_read_memory(target, addr1, 1, len1,
952 if (retval != ERROR_OK) {
957 retval = target_read_memory(target, addr2, 1, len2,
959 if (retval != ERROR_OK) {
966 semihosting->result = rename((char *)fn1,
968 semihosting->sys_errno = errno;
969 LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
970 (int)semihosting->result);
979 case SEMIHOSTING_SYS_SEEK: /* 0x0A */
981 * Seeks to a specified position in a file using an offset
982 * specified from the start of the file. The file is assumed
983 * to be a byte array and the offset is given in bytes.
986 * On entry, the PARAMETER REGISTER contains a pointer to a
987 * two-field data block:
988 * - field 1 A handle for a seekable file object.
989 * - field 2 The absolute byte position to seek to.
992 * On exit, the RETURN REGISTER contains:
993 * - 0 if the request is successful.
994 * - A negative value if the request is not successful.
995 * Use SYS_ERRNO to read the value of the host errno variable
996 * describing the error.
998 * Note: The effect of seeking outside the current extent of
999 * the file object is undefined.
1001 retval = semihosting_read_fields(target, 2, fields);
1002 if (retval != ERROR_OK)
1005 int fd = semihosting_get_field(target, 0, fields);
1006 off_t pos = semihosting_get_field(target, 1, fields);
1007 if (semihosting->is_fileio) {
1008 semihosting->hit_fileio = true;
1009 fileio_info->identifier = "lseek";
1010 fileio_info->param_1 = fd;
1011 fileio_info->param_2 = pos;
1012 fileio_info->param_3 = SEEK_SET;
1014 semihosting->result = lseek(fd, pos, SEEK_SET);
1015 semihosting->sys_errno = errno;
1016 LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
1017 (int)semihosting->result);
1018 if (semihosting->result == pos)
1019 semihosting->result = 0;
1024 case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
1026 * Passes a command to the host command-line interpreter.
1027 * This enables you to execute a system command such as dir,
1028 * ls, or pwd. The terminal I/O is on the host, and is not
1029 * visible to the target.
1032 * On entry, the PARAMETER REGISTER contains a pointer to a
1033 * two-field argument block:
1034 * - field 1 Points to a string to be passed to the host
1035 * command-line interpreter.
1036 * - field 2 The length of the string.
1039 * On exit, the RETURN REGISTER contains the return status.
1042 /* Provide SYS_SYSTEM functionality. Uses the
1043 * libc system command, there may be a reason *NOT*
1044 * to use this, but as I can't think of one, I
1045 * implemented it this way.
1047 retval = semihosting_read_fields(target, 2, fields);
1048 if (retval != ERROR_OK)
1051 uint64_t addr = semihosting_get_field(target, 0, fields);
1052 size_t len = semihosting_get_field(target, 1, fields);
1053 if (semihosting->is_fileio) {
1054 semihosting->hit_fileio = true;
1055 fileio_info->identifier = "system";
1056 fileio_info->param_1 = addr;
1057 fileio_info->param_2 = len;
1059 uint8_t *cmd = malloc(len+1);
1061 semihosting->result = -1;
1062 semihosting->sys_errno = ENOMEM;
1064 retval = target_read_memory(target,
1069 if (retval != ERROR_OK) {
1074 semihosting->result = system(
1076 LOG_DEBUG("system('%s')=%d",
1078 (int)semihosting->result);
1087 case SEMIHOSTING_SYS_TIME: /* 0x11 */
1089 * Returns the number of seconds since 00:00 January 1, 1970.
1090 * This value is real-world time, regardless of any debug agent
1094 * There are no parameters.
1097 * On exit, the RETURN REGISTER contains the number of seconds.
1099 semihosting->result = time(NULL);
1102 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1104 * Writes the contents of a buffer to a specified file at the
1105 * current file position. The file position is specified either:
1106 * - Explicitly, by a SYS_SEEK.
1107 * - Implicitly as one byte beyond the previous SYS_READ or
1108 * SYS_WRITE request.
1110 * The file position is at the start of the file when the file
1111 * is opened, and is lost when the file is closed.
1113 * Perform the file operation as a single action whenever
1114 * possible. For example, do not split a write of 16KB into
1115 * four 4KB chunks unless there is no alternative.
1118 * On entry, the PARAMETER REGISTER contains a pointer to a
1119 * three-field data block:
1120 * - field 1 Contains a handle for a file previously opened
1122 * - field 2 Points to the memory containing the data to be written.
1123 * - field 3 Contains the number of bytes to be written from
1124 * the buffer to the file.
1127 * On exit, the RETURN REGISTER contains:
1128 * - 0 if the call is successful.
1129 * - The number of bytes that are not written, if there is an error.
1131 retval = semihosting_read_fields(target, 3, fields);
1132 if (retval != ERROR_OK)
1135 int fd = semihosting_get_field(target, 0, fields);
1136 uint64_t addr = semihosting_get_field(target, 1, fields);
1137 size_t len = semihosting_get_field(target, 2, fields);
1138 if (semihosting->is_fileio) {
1139 semihosting->hit_fileio = true;
1140 fileio_info->identifier = "write";
1141 fileio_info->param_1 = fd;
1142 fileio_info->param_2 = addr;
1143 fileio_info->param_3 = len;
1145 uint8_t *buf = malloc(len);
1147 semihosting->result = -1;
1148 semihosting->sys_errno = ENOMEM;
1150 retval = target_read_buffer(target, addr, len, buf);
1151 if (retval != ERROR_OK) {
1155 semihosting->result = write(fd, buf, len);
1156 semihosting->sys_errno = errno;
1157 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
1161 (int)semihosting->result);
1162 if (semihosting->result >= 0) {
1163 /* The number of bytes that are NOT written.
1165 semihosting->result = len -
1166 semihosting->result;
1175 case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
1177 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1178 * to the debug channel. When executed under a semihosting
1179 * debugger, the character appears on the host debugger console.
1182 * On entry, the PARAMETER REGISTER contains a pointer to the
1186 * None. The RETURN REGISTER is corrupted.
1188 if (semihosting->is_fileio) {
1189 semihosting->hit_fileio = true;
1190 fileio_info->identifier = "write";
1191 fileio_info->param_1 = 1;
1192 fileio_info->param_2 = semihosting->param;
1193 fileio_info->param_3 = 1;
1195 uint64_t addr = semihosting->param;
1197 retval = target_read_memory(target, addr, 1, 1, &c);
1198 if (retval != ERROR_OK)
1201 semihosting->result = 0;
1205 case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
1207 * Writes a null-terminated string to the debug channel.
1208 * When executed under a semihosting debugger, the characters
1209 * appear on the host debugger console.
1212 * On entry, the PARAMETER REGISTER contains a pointer to the
1213 * first byte of the string.
1216 * None. The RETURN REGISTER is corrupted.
1218 if (semihosting->is_fileio) {
1220 uint64_t addr = semihosting->param;
1223 retval = target_read_memory(target, addr, 1, 1, &c);
1224 if (retval != ERROR_OK)
1230 semihosting->hit_fileio = true;
1231 fileio_info->identifier = "write";
1232 fileio_info->param_1 = 1;
1233 fileio_info->param_2 = semihosting->param;
1234 fileio_info->param_3 = count;
1236 uint64_t addr = semihosting->param;
1239 retval = target_read_memory(target, addr++, 1, 1, &c);
1240 if (retval != ERROR_OK)
1246 semihosting->result = 0;
1250 case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
1252 * Returns the number of elapsed target ticks since execution
1254 * Use SYS_TICKFREQ to determine the tick frequency.
1257 * On entry, the PARAMETER REGISTER points to a two-field data
1258 * block to be used for returning the number of elapsed ticks:
1259 * - field 1 The least significant field and is at the low address.
1260 * - field 2 The most significant field and is at the high address.
1263 * On entry the PARAMETER REGISTER points to a one-field data
1264 * block to be used for returning the number of elapsed ticks:
1265 * - field 1 The number of elapsed ticks as a 64-bit value.
1269 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1270 * REGISTER is unchanged, and the data block pointed to by the
1271 * PARAMETER REGISTER is filled in with the number of elapsed
1273 * - On failure, the RETURN REGISTER contains -1, and the
1274 * PARAMETER REGISTER contains -1.
1276 * Note: Some semihosting implementations might not support this
1277 * semihosting operation, and they always return -1 in the
1281 case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
1283 * Returns the tick frequency.
1286 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1289 * On exit, the RETURN REGISTER contains either:
1290 * - The number of ticks per second.
1291 * - –1 if the target does not know the value of one tick.
1293 * Note: Some semihosting implementations might not support
1294 * this semihosting operation, and they always return -1 in the
1298 case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
1300 * Returns a temporary name for a file identified by a system
1304 * On entry, the PARAMETER REGISTER contains a pointer to a
1305 * three-word argument block:
1306 * - field 1 A pointer to a buffer.
1307 * - field 2 A target identifier for this filename. Its value
1308 * must be an integer in the range 0-255.
1309 * - field 3 Contains the length of the buffer. The length must
1310 * be at least the value of L_tmpnam on the host system.
1313 * On exit, the RETURN REGISTER contains:
1314 * - 0 if the call is successful.
1315 * - –1 if an error occurs.
1317 * The buffer pointed to by the PARAMETER REGISTER contains
1318 * the filename, prefixed with a suitable directory name.
1319 * If you use the same target identifier again, the same
1320 * filename is returned.
1322 * Note: The returned string must be null-terminated.
1326 fprintf(stderr, "semihosting: unsupported call %#x\n",
1327 (unsigned) semihosting->op);
1328 semihosting->result = -1;
1329 semihosting->sys_errno = ENOTSUP;
1332 if (!semihosting->hit_fileio) {
1333 retval = semihosting->post_result(target);
1334 if (retval != ERROR_OK) {
1335 LOG_ERROR("Failed to post semihosting result");
1343 /* -------------------------------------------------------------------------
1344 * Local functions. */
1346 static int semihosting_common_fileio_info(struct target *target,
1347 struct gdb_fileio_info *fileio_info)
1349 struct semihosting *semihosting = target->semihosting;
1354 * To avoid unnecessary duplication, semihosting prepares the
1355 * fileio_info structure out-of-band when the target halts. See
1356 * do_semihosting for more detail.
1358 if (!semihosting->is_fileio || !semihosting->hit_fileio)
1364 static int semihosting_common_fileio_end(struct target *target, int result,
1365 int fileio_errno, bool ctrl_c)
1367 struct gdb_fileio_info *fileio_info = target->fileio_info;
1368 struct semihosting *semihosting = target->semihosting;
1372 /* clear pending status */
1373 semihosting->hit_fileio = false;
1375 semihosting->result = result;
1376 semihosting->sys_errno = fileio_errno;
1379 * Some fileio results do not match up with what the semihosting
1380 * operation expects; for these operations, we munge the results
1383 switch (semihosting->op) {
1384 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1386 semihosting->result = fileio_info->param_3;
1388 semihosting->result = 0;
1391 case SEMIHOSTING_SYS_READ: /* 0x06 */
1392 if (result == (int)fileio_info->param_3)
1393 semihosting->result = 0;
1395 semihosting->result = fileio_info->param_3;
1398 case SEMIHOSTING_SYS_SEEK: /* 0x0a */
1400 semihosting->result = 0;
1404 return semihosting->post_result(target);
1408 * Read all fields of a command from target to buffer.
1410 static int semihosting_read_fields(struct target *target, size_t number,
1413 struct semihosting *semihosting = target->semihosting;
1414 /* Use 4-byte multiples to trigger fast memory access. */
1415 return target_read_memory(target, semihosting->param, 4,
1416 number * (semihosting->word_size_bytes / 4), fields);
1420 * Write all fields of a command from buffer to target.
1422 static int semihosting_write_fields(struct target *target, size_t number,
1425 struct semihosting *semihosting = target->semihosting;
1426 /* Use 4-byte multiples to trigger fast memory access. */
1427 return target_write_memory(target, semihosting->param, 4,
1428 number * (semihosting->word_size_bytes / 4), fields);
1432 * Extract a field from the buffer, considering register size and endianness.
1434 static uint64_t semihosting_get_field(struct target *target, size_t index,
1437 struct semihosting *semihosting = target->semihosting;
1438 if (semihosting->word_size_bytes == 8)
1439 return target_buffer_get_u64(target, fields + (index * 8));
1441 return target_buffer_get_u32(target, fields + (index * 4));
1445 * Store a field in the buffer, considering register size and endianness.
1447 static void semihosting_set_field(struct target *target, uint64_t value,
1451 struct semihosting *semihosting = target->semihosting;
1452 if (semihosting->word_size_bytes == 8)
1453 target_buffer_set_u64(target, fields + (index * 8), value);
1455 target_buffer_set_u32(target, fields + (index * 4), value);
1459 /* -------------------------------------------------------------------------
1460 * Common semihosting commands handlers. */
1462 __COMMAND_HANDLER(handle_common_semihosting_command)
1464 struct target *target = get_current_target(CMD_CTX);
1466 if (target == NULL) {
1467 LOG_ERROR("No target selected");
1471 struct semihosting *semihosting = target->semihosting;
1473 command_print(CMD_CTX, "semihosting not supported for current target");
1480 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1482 if (!target_was_examined(target)) {
1483 LOG_ERROR("Target not examined yet");
1487 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1488 LOG_ERROR("Failed to Configure semihosting");
1492 /* FIXME never let that "catch" be dropped! (???) */
1493 semihosting->is_active = is_active;
1496 command_print(CMD_CTX, "semihosting is %s",
1497 semihosting->is_active
1498 ? "enabled" : "disabled");
1504 __COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1506 struct target *target = get_current_target(CMD_CTX);
1508 if (target == NULL) {
1509 LOG_ERROR("No target selected");
1513 struct semihosting *semihosting = target->semihosting;
1515 command_print(CMD_CTX, "semihosting not supported for current target");
1519 if (!semihosting->is_active) {
1520 command_print(CMD_CTX, "semihosting not yet enabled for current target");
1525 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1527 command_print(CMD_CTX, "semihosting fileio is %s",
1528 semihosting->is_fileio
1529 ? "enabled" : "disabled");
1534 __COMMAND_HANDLER(handle_common_semihosting_cmdline)
1536 struct target *target = get_current_target(CMD_CTX);
1539 if (target == NULL) {
1540 LOG_ERROR("No target selected");
1544 struct semihosting *semihosting = target->semihosting;
1546 command_print(CMD_CTX, "semihosting not supported for current target");
1550 free(semihosting->cmdline);
1551 semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1553 for (i = 1; i < CMD_ARGC; i++) {
1554 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1555 if (cmdline == NULL)
1557 free(semihosting->cmdline);
1558 semihosting->cmdline = cmdline;
1561 command_print(CMD_CTX, "semihosting command line is [%s]",
1562 semihosting->cmdline);
1567 __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1569 struct target *target = get_current_target(CMD_CTX);
1571 if (target == NULL) {
1572 LOG_ERROR("No target selected");
1576 struct semihosting *semihosting = target->semihosting;
1578 command_print(CMD_CTX, "semihosting not supported for current target");
1582 if (!semihosting->is_active) {
1583 command_print(CMD_CTX, "semihosting not yet enabled for current target");
1588 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
1590 command_print(CMD_CTX, "semihosting resumable exit is %s",
1591 semihosting->has_resumable_exit
1592 ? "enabled" : "disabled");