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>
56 * It is not possible to use O_... flags defined in sys/stat.h because they
57 * are not guaranteed to match the values defined by the GDB Remote Protocol.
58 * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
61 TARGET_O_RDONLY = 0x000,
62 TARGET_O_WRONLY = 0x001,
63 TARGET_O_RDWR = 0x002,
64 TARGET_O_APPEND = 0x008,
65 TARGET_O_CREAT = 0x200,
66 TARGET_O_TRUNC = 0x400,
67 /* O_EXCL=0x800 is not required in this implementation. */
70 /* GDB remote protocol does not differentiate between text and binary open modes. */
71 static const int open_modeflags[12] = {
76 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
77 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
78 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC,
79 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC,
80 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
81 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
82 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND,
83 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND
86 static int semihosting_common_fileio_info(struct target *target,
87 struct gdb_fileio_info *fileio_info);
88 static int semihosting_common_fileio_end(struct target *target, int result,
89 int fileio_errno, bool ctrl_c);
91 static int semihosting_read_fields(struct target *target, size_t number,
93 static int semihosting_write_fields(struct target *target, size_t number,
95 static uint64_t semihosting_get_field(struct target *target, size_t index,
97 static void semihosting_set_field(struct target *target, uint64_t value,
101 /* Attempts to include gdb_server.h failed. */
102 extern int gdb_actual_connections;
105 * Initialize common semihosting support.
107 * @param target Pointer to the target to initialize.
110 * @return An error status if there is a problem during initialization.
112 int semihosting_common_init(struct target *target, void *setup,
117 target->fileio_info = malloc(sizeof(*target->fileio_info));
118 if (!target->fileio_info) {
119 LOG_ERROR("out of memory");
122 memset(target->fileio_info, 0, sizeof(*target->fileio_info));
124 struct semihosting *semihosting;
125 semihosting = malloc(sizeof(*target->semihosting));
127 LOG_ERROR("out of memory");
131 semihosting->is_active = false;
132 semihosting->is_fileio = false;
133 semihosting->hit_fileio = false;
134 semihosting->is_resumable = false;
135 semihosting->has_resumable_exit = false;
136 semihosting->word_size_bytes = 0;
137 semihosting->op = -1;
138 semihosting->param = 0;
139 semihosting->result = -1;
140 semihosting->sys_errno = -1;
141 semihosting->cmdline = NULL;
143 /* If possible, update it in setup(). */
144 semihosting->setup_time = clock();
146 semihosting->setup = setup;
147 semihosting->post_result = post_result;
149 target->semihosting = semihosting;
151 target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
152 target->type->gdb_fileio_end = semihosting_common_fileio_end;
158 * User operation parameter string storage buffer. Contains valid data when the
159 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
161 static char *semihosting_user_op_params;
164 * Portable implementation of ARM semihosting calls.
165 * Performs the currently pending semihosting operation
166 * encoded in target->semihosting.
168 int semihosting_common(struct target *target)
170 struct semihosting *semihosting = target->semihosting;
172 /* Silently ignore if the semihosting field was not set. */
176 struct gdb_fileio_info *fileio_info = target->fileio_info;
179 * By default return an error.
180 * The actual result must be set by each function
182 semihosting->result = -1;
184 /* Most operations are resumable, except the two exit calls. */
185 semihosting->is_resumable = true;
189 /* Enough space to hold 4 long words. */
192 LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op,
195 switch (semihosting->op) {
197 case SEMIHOSTING_SYS_CLOCK: /* 0x10 */
199 * Returns the number of centiseconds (hundredths of a second)
200 * since the execution started.
202 * Values returned can be of limited use for some benchmarking
203 * purposes because of communication overhead or other
204 * agent-specific factors. For example, with a debug hardware
205 * unit the request is passed back to the host for execution.
206 * This can lead to unpredictable delays in transmission and
207 * process scheduling.
209 * Use this function to calculate time intervals, by calculating
210 * differences between intervals with and without the code
211 * sequence to be timed.
214 * The PARAMETER REGISTER must contain 0. There are no other
218 * On exit, the RETURN REGISTER contains:
219 * - The number of centiseconds since some arbitrary start
220 * point, if the call is successful.
221 * - –1 if the call is not successful. For example, because
222 * of a communications error.
225 clock_t delta = clock() - semihosting->setup_time;
227 semihosting->result = delta / (CLOCKS_PER_SEC / 100);
231 case SEMIHOSTING_SYS_CLOSE: /* 0x02 */
233 * Closes a file on the host system. The handle must reference
234 * a file that was opened with SYS_OPEN.
237 * On entry, the PARAMETER REGISTER contains a pointer to a
238 * one-field argument block:
239 * - field 1 Contains a handle for an open file.
242 * On exit, the RETURN REGISTER contains:
243 * - 0 if the call is successful
244 * - –1 if the call is not successful.
246 retval = semihosting_read_fields(target, 1, fields);
247 if (retval != ERROR_OK)
250 int fd = semihosting_get_field(target, 0, fields);
251 /* Do not allow to close OpenOCD's own standard streams */
252 if (fd == 0 || fd == 1 || fd == 2) {
253 LOG_DEBUG("ignoring semihosting attempt to close %s",
254 (fd == 0) ? "stdin" :
255 (fd == 1) ? "stdout" : "stderr");
256 /* Just pretend success */
257 if (semihosting->is_fileio) {
258 semihosting->result = 0;
260 semihosting->result = 0;
261 semihosting->sys_errno = 0;
265 /* Close the descriptor */
266 if (semihosting->is_fileio) {
267 semihosting->hit_fileio = true;
268 fileio_info->identifier = "close";
269 fileio_info->param_1 = fd;
271 semihosting->result = close(fd);
272 semihosting->sys_errno = errno;
273 LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
278 case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
280 * Returns the value of the C library errno variable that is
281 * associated with the semihosting implementation. The errno
282 * variable can be set by a number of C library semihosted
283 * functions, including:
291 * Whether errno is set or not, and to what value, is entirely
292 * host-specific, except where the ISO C standard defines the
296 * There are no parameters. The PARAMETER REGISTER must be 0.
299 * On exit, the RETURN REGISTER contains the value of the C
300 * library errno variable.
302 semihosting->result = semihosting->sys_errno;
305 case SEMIHOSTING_SYS_EXIT: /* 0x18 */
307 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
308 * previous versions of the documentation.
310 * An application calls this operation to report an exception
311 * to the debugger directly. The most common use is to report
312 * that execution has completed, using ADP_Stopped_ApplicationExit.
314 * Note: This semihosting operation provides no means for 32-bit
315 * callers to indicate an application exit with a specified exit
316 * code. Semihosting callers may prefer to check for the presence
317 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
318 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
322 * On entry, the PARAMETER register is set to a reason code
323 * describing the cause of the trap. Not all semihosting client
324 * implementations will necessarily trap every corresponding
325 * event. Important reason codes are:
327 * - ADP_Stopped_ApplicationExit 0x20026
328 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
331 * On entry, the PARAMETER REGISTER contains a pointer to a
332 * two-field argument block:
333 * - field 1 The exception type, which is one of the set of
334 * reason codes in the above tables.
335 * - field 2 A subcode, whose meaning depends on the reason
337 * In particular, if field 1 is ADP_Stopped_ApplicationExit
338 * then field 2 is an exit status code, as passed to the C
339 * standard library exit() function. A simulator receiving
340 * this request must notify a connected debugger, if present,
341 * and then exit with the specified status.
344 * No return is expected from these calls. However, it is
345 * possible for the debugger to request that the application
346 * continues by performing an RDI_Execute request or equivalent.
347 * In this case, execution continues with the registers as they
348 * were on entry to the operation, or as subsequently modified
351 if (semihosting->word_size_bytes == 8) {
352 retval = semihosting_read_fields(target, 2, fields);
353 if (retval != ERROR_OK)
356 int type = semihosting_get_field(target, 0, fields);
357 int code = semihosting_get_field(target, 1, fields);
359 if (type == ADP_STOPPED_APPLICATION_EXIT) {
360 if (!gdb_actual_connections)
364 "semihosting: *** application exited with %d ***\n",
369 "semihosting: application exception %#x\n",
374 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
375 if (!gdb_actual_connections)
379 "semihosting: *** application exited normally ***\n");
381 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
382 /* Chosen more or less arbitrarily to have a nicer message,
383 * otherwise all other return the same exit code 1. */
384 if (!gdb_actual_connections)
388 "semihosting: *** application exited with error ***\n");
391 if (!gdb_actual_connections)
395 "semihosting: application exception %#x\n",
396 (unsigned) semihosting->param);
400 if (!semihosting->has_resumable_exit) {
401 semihosting->is_resumable = false;
402 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
406 case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
408 * This operation is only supported if the semihosting extension
409 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
410 * reported using feature byte 0, bit 0. If this extension is
411 * supported, then the implementation provides a means to
412 * report a normal exit with a nonzero exit status in both 32-bit
413 * and 64-bit semihosting APIs.
415 * The implementation must provide the semihosting call
416 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
418 * SYS_EXIT_EXTENDED is used by an application to report an
419 * exception or exit to the debugger directly. The most common
420 * use is to report that execution has completed, using
421 * ADP_Stopped_ApplicationExit.
424 * On entry, the PARAMETER REGISTER contains a pointer to a
425 * two-field argument block:
426 * - field 1 The exception type, which should be one of the set
427 * of reason codes that are documented for the SYS_EXIT
428 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
429 * - field 2 A subcode, whose meaning depends on the reason
430 * code in field 1. In particular, if field 1 is
431 * ADP_Stopped_ApplicationExit then field 2 is an exit status
432 * code, as passed to the C standard library exit() function.
433 * A simulator receiving this request must notify a connected
434 * debugger, if present, and then exit with the specified status.
437 * No return is expected from these calls.
439 * For the A64 API, this call is identical to the behavior of
440 * the mandatory SYS_EXIT (0x18) call. If this extension is
441 * supported, then both calls must be implemented.
443 retval = semihosting_read_fields(target, 2, fields);
444 if (retval != ERROR_OK)
447 int type = semihosting_get_field(target, 0, fields);
448 int code = semihosting_get_field(target, 1, fields);
450 if (type == ADP_STOPPED_APPLICATION_EXIT) {
451 if (!gdb_actual_connections)
455 "semihosting: *** application exited with %d ***\n",
459 fprintf(stderr, "semihosting: exception %#x\n",
463 if (!semihosting->has_resumable_exit) {
464 semihosting->is_resumable = false;
465 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
469 case SEMIHOSTING_SYS_FLEN: /* 0x0C */
471 * Returns the length of a specified file.
474 * On entry, the PARAMETER REGISTER contains a pointer to a
475 * one-field argument block:
476 * - field 1 A handle for a previously opened, seekable file
480 * On exit, the RETURN REGISTER contains:
481 * - The current length of the file object, if the call is
483 * - –1 if an error occurs.
485 if (semihosting->is_fileio) {
486 semihosting->result = -1;
487 semihosting->sys_errno = EINVAL;
489 retval = semihosting_read_fields(target, 1, fields);
490 if (retval != ERROR_OK)
493 int fd = semihosting_get_field(target, 0, fields);
495 semihosting->result = fstat(fd, &buf);
496 if (semihosting->result == -1) {
497 semihosting->sys_errno = errno;
498 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
501 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
502 semihosting->result = buf.st_size;
506 case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
508 * Returns the command line that is used for the call to the
509 * executable, that is, argc and argv.
512 * On entry, the PARAMETER REGISTER points to a two-field data
513 * block to be used for returning the command string and its length:
514 * - field 1 A pointer to a buffer of at least the size that is
515 * specified in field 2.
516 * - field 2 The length of the buffer in bytes.
520 * If the call is successful, then the RETURN REGISTER contains 0,
521 * the PARAMETER REGISTER is unchanged, and the data block is
522 * updated as follows:
523 * - field 1 A pointer to a null-terminated string of the command
525 * - field 2 The length of the string in bytes.
526 * If the call is not successful, then the RETURN REGISTER
529 * Note: The semihosting implementation might impose limits on
530 * the maximum length of the string that can be transferred.
531 * However, the implementation must be able to support a
532 * command-line length of at least 80 bytes.
534 retval = semihosting_read_fields(target, 2, fields);
535 if (retval != ERROR_OK)
538 uint64_t addr = semihosting_get_field(target, 0, fields);
539 size_t size = semihosting_get_field(target, 1, fields);
541 char *arg = semihosting->cmdline ?
542 semihosting->cmdline : "";
543 uint32_t len = strlen(arg) + 1;
545 semihosting->result = -1;
547 semihosting_set_field(target, len, 1, fields);
548 retval = target_write_buffer(target, addr, len,
550 if (retval != ERROR_OK)
552 semihosting->result = 0;
554 retval = semihosting_write_fields(target, 2, fields);
555 if (retval != ERROR_OK)
558 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
559 (int)semihosting->result);
563 case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
565 * Returns the system stack and heap parameters.
568 * On entry, the PARAMETER REGISTER contains the address of a
569 * pointer to a four-field data block. The contents of the data
570 * block are filled by the function. The following C-like
571 * pseudocode describes the layout of the block:
580 * On exit, the PARAMETER REGISTER is unchanged and the data
581 * block has been updated.
583 retval = semihosting_read_fields(target, 1, fields);
584 if (retval != ERROR_OK)
587 uint64_t addr = semihosting_get_field(target, 0, fields);
588 /* tell the remote we have no idea */
589 memset(fields, 0, 4 * semihosting->word_size_bytes);
590 retval = target_write_memory(target, addr, 4,
591 semihosting->word_size_bytes,
593 if (retval != ERROR_OK)
595 semihosting->result = 0;
599 case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
601 * Determines whether the return code from another semihosting
602 * call is an error status or not.
604 * This call is passed a parameter block containing the error
608 * On entry, the PARAMETER REGISTER contains a pointer to a
609 * one-field data block:
610 * - field 1 The required status word to check.
613 * On exit, the RETURN REGISTER contains:
614 * - 0 if the status field is not an error indication
615 * - A nonzero value if the status field is an error indication.
617 retval = semihosting_read_fields(target, 1, fields);
618 if (retval != ERROR_OK)
621 uint64_t code = semihosting_get_field(target, 0, fields);
622 semihosting->result = (code != 0);
625 case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
627 * Checks whether a file is connected to an interactive device.
630 * On entry, the PARAMETER REGISTER contains a pointer to a
631 * one-field argument block:
632 * field 1 A handle for a previously opened file object.
635 * On exit, the RETURN REGISTER contains:
636 * - 1 if the handle identifies an interactive device.
637 * - 0 if the handle identifies a file.
638 * - A value other than 1 or 0 if an error occurs.
640 if (semihosting->is_fileio) {
641 semihosting->hit_fileio = true;
642 fileio_info->identifier = "isatty";
643 fileio_info->param_1 = semihosting->param;
645 retval = semihosting_read_fields(target, 1, fields);
646 if (retval != ERROR_OK)
648 int fd = semihosting_get_field(target, 0, fields);
649 semihosting->result = isatty(fd);
650 semihosting->sys_errno = errno;
651 LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
655 case SEMIHOSTING_SYS_OPEN: /* 0x01 */
657 * Opens a file on the host system.
659 * The file path is specified either as relative to the current
660 * directory of the host process, or absolute, using the path
661 * conventions of the host operating system.
663 * Semihosting implementations must support opening the special
664 * path name :semihosting-features as part of the semihosting
665 * extensions reporting mechanism.
667 * ARM targets interpret the special path name :tt as meaning
668 * the console input stream, for an open-read or the console
669 * output stream, for an open-write. Opening these streams is
670 * performed as part of the standard startup code for those
671 * applications that reference the C stdio streams. The
672 * semihosting extension SH_EXT_STDOUT_STDERR allows the
673 * semihosting caller to open separate output streams
674 * corresponding to stdout and stderr. This extension is
675 * reported using feature byte 0, bit 1. Use SYS_OPEN with
676 * the special path name :semihosting-features to access the
679 * If this extension is supported, the implementation must
680 * support the following additional semantics to SYS_OPEN:
681 * - If the special path name :tt is opened with an fopen
682 * mode requesting write access (w, wb, w+, or w+b), then
683 * this is a request to open stdout.
684 * - If the special path name :tt is opened with a mode
685 * requesting append access (a, ab, a+, or a+b), then this is
686 * a request to open stderr.
689 * On entry, the PARAMETER REGISTER contains a pointer to a
690 * three-field argument block:
691 * - field 1 A pointer to a null-terminated string containing
692 * a file or device name.
693 * - field 2 An integer that specifies the file opening mode.
694 * - field 3 An integer that gives the length of the string
695 * pointed to by field 1.
697 * The length does not include the terminating null character
698 * that must be present.
701 * On exit, the RETURN REGISTER contains:
702 * - A nonzero handle if the call is successful.
703 * - –1 if the call is not successful.
705 retval = semihosting_read_fields(target, 3, fields);
706 if (retval != ERROR_OK)
709 uint64_t addr = semihosting_get_field(target, 0, fields);
710 uint32_t mode = semihosting_get_field(target, 1, fields);
711 size_t len = semihosting_get_field(target, 2, fields);
714 semihosting->result = -1;
715 semihosting->sys_errno = EINVAL;
718 uint8_t *fn = malloc(len+1);
720 semihosting->result = -1;
721 semihosting->sys_errno = ENOMEM;
723 retval = target_read_memory(target, addr, 1, len, fn);
724 if (retval != ERROR_OK) {
729 /* TODO: implement the :semihosting-features special file.
731 if (semihosting->is_fileio) {
732 if (strcmp((char *)fn, ":semihosting-features") == 0) {
733 semihosting->result = -1;
734 semihosting->sys_errno = EINVAL;
735 } else if (strcmp((char *)fn, ":tt") == 0) {
737 semihosting->result = 0;
739 semihosting->result = 1;
741 semihosting->result = 2;
743 semihosting->result = -1;
745 semihosting->hit_fileio = true;
746 fileio_info->identifier = "open";
747 fileio_info->param_1 = addr;
748 fileio_info->param_2 = len;
749 fileio_info->param_3 = open_modeflags[mode];
750 fileio_info->param_4 = 0644;
753 if (strcmp((char *)fn, ":tt") == 0) {
755 * - 0-3 ("r") for stdin,
756 * - 4-7 ("w") for stdout,
757 * - 8-11 ("a") for stderr */
759 semihosting->result = dup(
761 semihosting->sys_errno = errno;
762 LOG_DEBUG("dup(STDIN)=%d",
763 (int)semihosting->result);
764 } else if (mode < 8) {
765 semihosting->result = dup(
767 semihosting->sys_errno = errno;
768 LOG_DEBUG("dup(STDOUT)=%d",
769 (int)semihosting->result);
771 semihosting->result = dup(
773 semihosting->sys_errno = errno;
774 LOG_DEBUG("dup(STDERR)=%d",
775 (int)semihosting->result);
778 /* cygwin requires the permission setting
779 * otherwise it will fail to reopen a previously
781 semihosting->result = open((char *)fn,
782 open_modeflags[mode],
784 semihosting->sys_errno = errno;
785 LOG_DEBUG("open('%s')=%d", fn,
786 (int)semihosting->result);
794 case SEMIHOSTING_SYS_READ: /* 0x06 */
796 * Reads the contents of a file into a buffer. The file position
797 * is specified either:
798 * - Explicitly by a SYS_SEEK.
799 * - Implicitly one byte beyond the previous SYS_READ or
802 * The file position is at the start of the file when it is
803 * opened, and is lost when the file is closed. Perform the
804 * file operation as a single action whenever possible. For
805 * example, do not split a read of 16KB into four 4KB chunks
806 * unless there is no alternative.
809 * On entry, the PARAMETER REGISTER contains a pointer to a
810 * three-field data block:
811 * - field 1 Contains a handle for a file previously opened
813 * - field 2 Points to a buffer.
814 * - field 3 Contains the number of bytes to read to the buffer
818 * On exit, the RETURN REGISTER contains the number of bytes not
819 * filled in the buffer (buffer_length - bytes_read) as follows:
820 * - If the RETURN REGISTER is 0, the entire buffer was
821 * successfully filled.
822 * - If the RETURN REGISTER is the same as field 3, no bytes
823 * were read (EOF can be assumed).
824 * - If the RETURN REGISTER contains a value smaller than
825 * field 3, the read succeeded but the buffer was only partly
826 * filled. For interactive devices, this is the most common
829 retval = semihosting_read_fields(target, 3, fields);
830 if (retval != ERROR_OK)
833 int fd = semihosting_get_field(target, 0, fields);
834 uint64_t addr = semihosting_get_field(target, 1, fields);
835 size_t len = semihosting_get_field(target, 2, fields);
836 if (semihosting->is_fileio) {
837 semihosting->hit_fileio = true;
838 fileio_info->identifier = "read";
839 fileio_info->param_1 = fd;
840 fileio_info->param_2 = addr;
841 fileio_info->param_3 = len;
843 uint8_t *buf = malloc(len);
845 semihosting->result = -1;
846 semihosting->sys_errno = ENOMEM;
848 semihosting->result = read(fd, buf, len);
849 semihosting->sys_errno = errno;
850 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
854 (int)semihosting->result);
855 if (semihosting->result >= 0) {
856 retval = target_write_buffer(target, addr,
859 if (retval != ERROR_OK) {
863 /* the number of bytes NOT filled in */
864 semihosting->result = len -
873 case SEMIHOSTING_SYS_READC: /* 0x07 */
875 * Reads a byte from the console.
878 * The PARAMETER REGISTER must contain 0. There are no other
879 * parameters or values possible.
882 * On exit, the RETURN REGISTER contains the byte read from
885 if (semihosting->is_fileio) {
886 LOG_ERROR("SYS_READC not supported by semihosting fileio");
889 semihosting->result = getchar();
890 LOG_DEBUG("getchar()=%d", (int)semihosting->result);
893 case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
895 * Deletes a specified file on the host filing system.
898 * On entry, the PARAMETER REGISTER contains a pointer to a
899 * two-field argument block:
900 * - field 1 Points to a null-terminated string that gives the
901 * path name of the file to be deleted.
902 * - field 2 The length of the string.
905 * On exit, the RETURN REGISTER contains:
906 * - 0 if the delete is successful
907 * - A nonzero, host-specific error code if the delete fails.
909 retval = semihosting_read_fields(target, 2, fields);
910 if (retval != ERROR_OK)
913 uint64_t addr = semihosting_get_field(target, 0, fields);
914 size_t len = semihosting_get_field(target, 1, fields);
915 if (semihosting->is_fileio) {
916 semihosting->hit_fileio = true;
917 fileio_info->identifier = "unlink";
918 fileio_info->param_1 = addr;
919 fileio_info->param_2 = len;
921 uint8_t *fn = malloc(len+1);
923 semihosting->result = -1;
924 semihosting->sys_errno = ENOMEM;
927 target_read_memory(target, addr, 1, len,
929 if (retval != ERROR_OK) {
934 semihosting->result = remove((char *)fn);
935 semihosting->sys_errno = errno;
936 LOG_DEBUG("remove('%s')=%d", fn,
937 (int)semihosting->result);
945 case SEMIHOSTING_SYS_RENAME: /* 0x0F */
947 * Renames a specified file.
950 * On entry, the PARAMETER REGISTER contains a pointer to a
951 * four-field data block:
952 * - field 1 A pointer to the name of the old file.
953 * - field 2 The length of the old filename.
954 * - field 3 A pointer to the new filename.
955 * - field 4 The length of the new filename. Both strings are
959 * On exit, the RETURN REGISTER contains:
960 * - 0 if the rename is successful.
961 * - A nonzero, host-specific error code if the rename fails.
963 retval = semihosting_read_fields(target, 4, fields);
964 if (retval != ERROR_OK)
967 uint64_t addr1 = semihosting_get_field(target, 0, fields);
968 size_t len1 = semihosting_get_field(target, 1, fields);
969 uint64_t addr2 = semihosting_get_field(target, 2, fields);
970 size_t len2 = semihosting_get_field(target, 3, fields);
971 if (semihosting->is_fileio) {
972 semihosting->hit_fileio = true;
973 fileio_info->identifier = "rename";
974 fileio_info->param_1 = addr1;
975 fileio_info->param_2 = len1;
976 fileio_info->param_3 = addr2;
977 fileio_info->param_4 = len2;
979 uint8_t *fn1 = malloc(len1+1);
980 uint8_t *fn2 = malloc(len2+1);
984 semihosting->result = -1;
985 semihosting->sys_errno = ENOMEM;
987 retval = target_read_memory(target, addr1, 1, len1,
989 if (retval != ERROR_OK) {
994 retval = target_read_memory(target, addr2, 1, len2,
996 if (retval != ERROR_OK) {
1003 semihosting->result = rename((char *)fn1,
1005 semihosting->sys_errno = errno;
1006 LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
1007 (int)semihosting->result);
1016 case SEMIHOSTING_SYS_SEEK: /* 0x0A */
1018 * Seeks to a specified position in a file using an offset
1019 * specified from the start of the file. The file is assumed
1020 * to be a byte array and the offset is given in bytes.
1023 * On entry, the PARAMETER REGISTER contains a pointer to a
1024 * two-field data block:
1025 * - field 1 A handle for a seekable file object.
1026 * - field 2 The absolute byte position to seek to.
1029 * On exit, the RETURN REGISTER contains:
1030 * - 0 if the request is successful.
1031 * - A negative value if the request is not successful.
1032 * Use SYS_ERRNO to read the value of the host errno variable
1033 * describing the error.
1035 * Note: The effect of seeking outside the current extent of
1036 * the file object is undefined.
1038 retval = semihosting_read_fields(target, 2, fields);
1039 if (retval != ERROR_OK)
1042 int fd = semihosting_get_field(target, 0, fields);
1043 off_t pos = semihosting_get_field(target, 1, fields);
1044 if (semihosting->is_fileio) {
1045 semihosting->hit_fileio = true;
1046 fileio_info->identifier = "lseek";
1047 fileio_info->param_1 = fd;
1048 fileio_info->param_2 = pos;
1049 fileio_info->param_3 = SEEK_SET;
1051 semihosting->result = lseek(fd, pos, SEEK_SET);
1052 semihosting->sys_errno = errno;
1053 LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
1054 (int)semihosting->result);
1055 if (semihosting->result == pos)
1056 semihosting->result = 0;
1061 case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
1063 * Passes a command to the host command-line interpreter.
1064 * This enables you to execute a system command such as dir,
1065 * ls, or pwd. The terminal I/O is on the host, and is not
1066 * visible to the target.
1069 * On entry, the PARAMETER REGISTER contains a pointer to a
1070 * two-field argument block:
1071 * - field 1 Points to a string to be passed to the host
1072 * command-line interpreter.
1073 * - field 2 The length of the string.
1076 * On exit, the RETURN REGISTER contains the return status.
1079 /* Provide SYS_SYSTEM functionality. Uses the
1080 * libc system command, there may be a reason *NOT*
1081 * to use this, but as I can't think of one, I
1082 * implemented it this way.
1084 retval = semihosting_read_fields(target, 2, fields);
1085 if (retval != ERROR_OK)
1088 uint64_t addr = semihosting_get_field(target, 0, fields);
1089 size_t len = semihosting_get_field(target, 1, fields);
1090 if (semihosting->is_fileio) {
1091 semihosting->hit_fileio = true;
1092 fileio_info->identifier = "system";
1093 fileio_info->param_1 = addr;
1094 fileio_info->param_2 = len;
1096 uint8_t *cmd = malloc(len+1);
1098 semihosting->result = -1;
1099 semihosting->sys_errno = ENOMEM;
1101 retval = target_read_memory(target,
1106 if (retval != ERROR_OK) {
1111 semihosting->result = system(
1113 LOG_DEBUG("system('%s')=%d",
1115 (int)semihosting->result);
1124 case SEMIHOSTING_SYS_TIME: /* 0x11 */
1126 * Returns the number of seconds since 00:00 January 1, 1970.
1127 * This value is real-world time, regardless of any debug agent
1131 * There are no parameters.
1134 * On exit, the RETURN REGISTER contains the number of seconds.
1136 semihosting->result = time(NULL);
1139 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1141 * Writes the contents of a buffer to a specified file at the
1142 * current file position. The file position is specified either:
1143 * - Explicitly, by a SYS_SEEK.
1144 * - Implicitly as one byte beyond the previous SYS_READ or
1145 * SYS_WRITE request.
1147 * The file position is at the start of the file when the file
1148 * is opened, and is lost when the file is closed.
1150 * Perform the file operation as a single action whenever
1151 * possible. For example, do not split a write of 16KB into
1152 * four 4KB chunks unless there is no alternative.
1155 * On entry, the PARAMETER REGISTER contains a pointer to a
1156 * three-field data block:
1157 * - field 1 Contains a handle for a file previously opened
1159 * - field 2 Points to the memory containing the data to be written.
1160 * - field 3 Contains the number of bytes to be written from
1161 * the buffer to the file.
1164 * On exit, the RETURN REGISTER contains:
1165 * - 0 if the call is successful.
1166 * - The number of bytes that are not written, if there is an error.
1168 retval = semihosting_read_fields(target, 3, fields);
1169 if (retval != ERROR_OK)
1172 int fd = semihosting_get_field(target, 0, fields);
1173 uint64_t addr = semihosting_get_field(target, 1, fields);
1174 size_t len = semihosting_get_field(target, 2, fields);
1175 if (semihosting->is_fileio) {
1176 semihosting->hit_fileio = true;
1177 fileio_info->identifier = "write";
1178 fileio_info->param_1 = fd;
1179 fileio_info->param_2 = addr;
1180 fileio_info->param_3 = len;
1182 uint8_t *buf = malloc(len);
1184 semihosting->result = -1;
1185 semihosting->sys_errno = ENOMEM;
1187 retval = target_read_buffer(target, addr, len, buf);
1188 if (retval != ERROR_OK) {
1192 semihosting->result = write(fd, buf, len);
1193 semihosting->sys_errno = errno;
1194 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
1198 (int)semihosting->result);
1199 if (semihosting->result >= 0) {
1200 /* The number of bytes that are NOT written.
1202 semihosting->result = len -
1203 semihosting->result;
1212 case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
1214 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1215 * to the debug channel. When executed under a semihosting
1216 * debugger, the character appears on the host debugger console.
1219 * On entry, the PARAMETER REGISTER contains a pointer to the
1223 * None. The RETURN REGISTER is corrupted.
1225 if (semihosting->is_fileio) {
1226 semihosting->hit_fileio = true;
1227 fileio_info->identifier = "write";
1228 fileio_info->param_1 = 1;
1229 fileio_info->param_2 = semihosting->param;
1230 fileio_info->param_3 = 1;
1232 uint64_t addr = semihosting->param;
1234 retval = target_read_memory(target, addr, 1, 1, &c);
1235 if (retval != ERROR_OK)
1238 semihosting->result = 0;
1242 case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
1244 * Writes a null-terminated string to the debug channel.
1245 * When executed under a semihosting debugger, the characters
1246 * appear on the host debugger console.
1249 * On entry, the PARAMETER REGISTER contains a pointer to the
1250 * first byte of the string.
1253 * None. The RETURN REGISTER is corrupted.
1255 if (semihosting->is_fileio) {
1257 uint64_t addr = semihosting->param;
1260 retval = target_read_memory(target, addr, 1, 1, &c);
1261 if (retval != ERROR_OK)
1267 semihosting->hit_fileio = true;
1268 fileio_info->identifier = "write";
1269 fileio_info->param_1 = 1;
1270 fileio_info->param_2 = semihosting->param;
1271 fileio_info->param_3 = count;
1273 uint64_t addr = semihosting->param;
1276 retval = target_read_memory(target, addr++, 1, 1, &c);
1277 if (retval != ERROR_OK)
1283 semihosting->result = 0;
1287 case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107:
1289 * This is a user defined operation (while user cmds 0x100-0x1ff
1290 * are possible, only 0x100-0x107 are currently implemented).
1292 * Reads the user operation parameters from target, then fires the
1293 * corresponding target event. When the target callbacks returned,
1294 * cleans up the command parameter buffer.
1297 * On entry, the PARAMETER REGISTER contains a pointer to a
1298 * two-field data block:
1299 * - field 1 Contains a pointer to the bound command parameter
1301 * - field 2 Contains the command parameter string length
1304 * On exit, the RETURN REGISTER contains the return status.
1307 assert(!semihosting_user_op_params);
1309 retval = semihosting_read_fields(target, 2, fields);
1310 if (retval != ERROR_OK) {
1311 LOG_ERROR("Failed to read fields for user defined command"
1312 " op=0x%x", semihosting->op);
1316 uint64_t addr = semihosting_get_field(target, 0, fields);
1318 size_t len = semihosting_get_field(target, 1, fields);
1319 if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
1320 LOG_ERROR("The maximum length for user defined command "
1321 "parameter is %u, received length is %zu (op=0x%x)",
1322 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
1328 semihosting_user_op_params = malloc(len + 1);
1329 if (!semihosting_user_op_params)
1331 semihosting_user_op_params[len] = 0;
1333 retval = target_read_buffer(target, addr, len,
1334 (uint8_t *)(semihosting_user_op_params));
1335 if (retval != ERROR_OK) {
1336 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1338 free(semihosting_user_op_params);
1339 semihosting_user_op_params = NULL;
1343 target_handle_event(target, semihosting->op);
1344 free(semihosting_user_op_params);
1345 semihosting_user_op_params = NULL;
1347 semihosting->result = 0;
1352 case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
1354 * Returns the number of elapsed target ticks since execution
1356 * Use SYS_TICKFREQ to determine the tick frequency.
1359 * On entry, the PARAMETER REGISTER points to a two-field data
1360 * block to be used for returning the number of elapsed ticks:
1361 * - field 1 The least significant field and is at the low address.
1362 * - field 2 The most significant field and is at the high address.
1365 * On entry the PARAMETER REGISTER points to a one-field data
1366 * block to be used for returning the number of elapsed ticks:
1367 * - field 1 The number of elapsed ticks as a 64-bit value.
1371 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1372 * REGISTER is unchanged, and the data block pointed to by the
1373 * PARAMETER REGISTER is filled in with the number of elapsed
1375 * - On failure, the RETURN REGISTER contains -1, and the
1376 * PARAMETER REGISTER contains -1.
1378 * Note: Some semihosting implementations might not support this
1379 * semihosting operation, and they always return -1 in the
1383 case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
1385 * Returns the tick frequency.
1388 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1391 * On exit, the RETURN REGISTER contains either:
1392 * - The number of ticks per second.
1393 * - –1 if the target does not know the value of one tick.
1395 * Note: Some semihosting implementations might not support
1396 * this semihosting operation, and they always return -1 in the
1400 case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
1402 * Returns a temporary name for a file identified by a system
1406 * On entry, the PARAMETER REGISTER contains a pointer to a
1407 * three-word argument block:
1408 * - field 1 A pointer to a buffer.
1409 * - field 2 A target identifier for this filename. Its value
1410 * must be an integer in the range 0-255.
1411 * - field 3 Contains the length of the buffer. The length must
1412 * be at least the value of L_tmpnam on the host system.
1415 * On exit, the RETURN REGISTER contains:
1416 * - 0 if the call is successful.
1417 * - –1 if an error occurs.
1419 * The buffer pointed to by the PARAMETER REGISTER contains
1420 * the filename, prefixed with a suitable directory name.
1421 * If you use the same target identifier again, the same
1422 * filename is returned.
1424 * Note: The returned string must be null-terminated.
1428 fprintf(stderr, "semihosting: unsupported call %#x\n",
1429 (unsigned) semihosting->op);
1430 semihosting->result = -1;
1431 semihosting->sys_errno = ENOTSUP;
1434 if (!semihosting->hit_fileio) {
1435 retval = semihosting->post_result(target);
1436 if (retval != ERROR_OK) {
1437 LOG_ERROR("Failed to post semihosting result");
1445 /* -------------------------------------------------------------------------
1446 * Local functions. */
1448 static int semihosting_common_fileio_info(struct target *target,
1449 struct gdb_fileio_info *fileio_info)
1451 struct semihosting *semihosting = target->semihosting;
1456 * To avoid unnecessary duplication, semihosting prepares the
1457 * fileio_info structure out-of-band when the target halts. See
1458 * do_semihosting for more detail.
1460 if (!semihosting->is_fileio || !semihosting->hit_fileio)
1466 static int semihosting_common_fileio_end(struct target *target, int result,
1467 int fileio_errno, bool ctrl_c)
1469 struct gdb_fileio_info *fileio_info = target->fileio_info;
1470 struct semihosting *semihosting = target->semihosting;
1474 /* clear pending status */
1475 semihosting->hit_fileio = false;
1477 semihosting->result = result;
1478 semihosting->sys_errno = fileio_errno;
1481 * Some fileio results do not match up with what the semihosting
1482 * operation expects; for these operations, we munge the results
1485 switch (semihosting->op) {
1486 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1488 semihosting->result = fileio_info->param_3;
1490 semihosting->result = 0;
1493 case SEMIHOSTING_SYS_READ: /* 0x06 */
1494 if (result == (int)fileio_info->param_3)
1495 semihosting->result = 0;
1497 semihosting->result = fileio_info->param_3;
1500 case SEMIHOSTING_SYS_SEEK: /* 0x0a */
1502 semihosting->result = 0;
1506 return semihosting->post_result(target);
1510 * Read all fields of a command from target to buffer.
1512 static int semihosting_read_fields(struct target *target, size_t number,
1515 struct semihosting *semihosting = target->semihosting;
1516 /* Use 4-byte multiples to trigger fast memory access. */
1517 return target_read_memory(target, semihosting->param, 4,
1518 number * (semihosting->word_size_bytes / 4), fields);
1522 * Write all fields of a command from buffer to target.
1524 static int semihosting_write_fields(struct target *target, size_t number,
1527 struct semihosting *semihosting = target->semihosting;
1528 /* Use 4-byte multiples to trigger fast memory access. */
1529 return target_write_memory(target, semihosting->param, 4,
1530 number * (semihosting->word_size_bytes / 4), fields);
1534 * Extract a field from the buffer, considering register size and endianness.
1536 static uint64_t semihosting_get_field(struct target *target, size_t index,
1539 struct semihosting *semihosting = target->semihosting;
1540 if (semihosting->word_size_bytes == 8)
1541 return target_buffer_get_u64(target, fields + (index * 8));
1543 return target_buffer_get_u32(target, fields + (index * 4));
1547 * Store a field in the buffer, considering register size and endianness.
1549 static void semihosting_set_field(struct target *target, uint64_t value,
1553 struct semihosting *semihosting = target->semihosting;
1554 if (semihosting->word_size_bytes == 8)
1555 target_buffer_set_u64(target, fields + (index * 8), value);
1557 target_buffer_set_u32(target, fields + (index * 4), value);
1561 /* -------------------------------------------------------------------------
1562 * Common semihosting commands handlers. */
1564 COMMAND_HANDLER(handle_common_semihosting_command)
1566 struct target *target = get_current_target(CMD_CTX);
1569 LOG_ERROR("No target selected");
1573 struct semihosting *semihosting = target->semihosting;
1575 command_print(CMD, "semihosting not supported for current target");
1582 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1584 if (!target_was_examined(target)) {
1585 LOG_ERROR("Target not examined yet");
1589 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1590 LOG_ERROR("Failed to Configure semihosting");
1594 /* FIXME never let that "catch" be dropped! (???) */
1595 semihosting->is_active = is_active;
1598 command_print(CMD, "semihosting is %s",
1599 semihosting->is_active
1600 ? "enabled" : "disabled");
1605 COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1607 struct target *target = get_current_target(CMD_CTX);
1610 LOG_ERROR("No target selected");
1614 struct semihosting *semihosting = target->semihosting;
1616 command_print(CMD, "semihosting not supported for current target");
1620 if (!semihosting->is_active) {
1621 command_print(CMD, "semihosting not yet enabled for current target");
1626 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1628 command_print(CMD, "semihosting fileio is %s",
1629 semihosting->is_fileio
1630 ? "enabled" : "disabled");
1635 COMMAND_HANDLER(handle_common_semihosting_cmdline)
1637 struct target *target = get_current_target(CMD_CTX);
1641 LOG_ERROR("No target selected");
1645 struct semihosting *semihosting = target->semihosting;
1647 command_print(CMD, "semihosting not supported for current target");
1651 free(semihosting->cmdline);
1652 semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1654 for (i = 1; i < CMD_ARGC; i++) {
1655 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1658 free(semihosting->cmdline);
1659 semihosting->cmdline = cmdline;
1662 command_print(CMD, "semihosting command line is [%s]",
1663 semihosting->cmdline);
1668 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1670 struct target *target = get_current_target(CMD_CTX);
1673 LOG_ERROR("No target selected");
1677 struct semihosting *semihosting = target->semihosting;
1679 command_print(CMD, "semihosting not supported for current target");
1683 if (!semihosting->is_active) {
1684 command_print(CMD, "semihosting not yet enabled for current target");
1689 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
1691 command_print(CMD, "semihosting resumable exit is %s",
1692 semihosting->has_resumable_exit
1693 ? "enabled" : "disabled");
1698 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
1700 struct target *target = get_current_target(CMD_CTX);
1701 struct semihosting *semihosting = target->semihosting;
1704 return ERROR_COMMAND_SYNTAX_ERROR;
1706 if (!semihosting->is_active) {
1707 LOG_ERROR("semihosting not yet enabled for current target");
1711 if (!semihosting_user_op_params) {
1712 LOG_ERROR("This command is usable only from a registered user "
1713 "semihosting event callback.");
1717 command_print_sameline(CMD, "%s", semihosting_user_op_params);
1722 const struct command_registration semihosting_common_handlers[] = {
1725 .handler = handle_common_semihosting_command,
1726 .mode = COMMAND_EXEC,
1727 .usage = "['enable'|'disable']",
1728 .help = "activate support for semihosting operations",
1731 "semihosting_cmdline",
1732 .handler = handle_common_semihosting_cmdline,
1733 .mode = COMMAND_EXEC,
1734 .usage = "arguments",
1735 .help = "command line arguments to be passed to program",
1738 "semihosting_fileio",
1739 .handler = handle_common_semihosting_fileio_command,
1740 .mode = COMMAND_EXEC,
1741 .usage = "['enable'|'disable']",
1742 .help = "activate support for semihosting fileio operations",
1745 "semihosting_resexit",
1746 .handler = handle_common_semihosting_resumable_exit_command,
1747 .mode = COMMAND_EXEC,
1748 .usage = "['enable'|'disable']",
1749 .help = "activate support for semihosting resumable exit",
1752 "semihosting_read_user_param",
1753 .handler = handle_common_semihosting_read_user_param_command,
1754 .mode = COMMAND_EXEC,
1756 .help = "read parameters in semihosting-user-cmd-0x10X callbacks",
1758 COMMAND_REGISTRATION_DONE