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 semihosting->hit_fileio = true;
229 fileio_info->identifier = "close";
230 fileio_info->param_1 = fd;
232 semihosting->result = close(fd);
233 semihosting->sys_errno = errno;
235 LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
240 case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
242 * Returns the value of the C library errno variable that is
243 * associated with the semihosting implementation. The errno
244 * variable can be set by a number of C library semihosted
245 * functions, including:
253 * Whether errno is set or not, and to what value, is entirely
254 * host-specific, except where the ISO C standard defines the
258 * There are no parameters. The PARAMETER REGISTER must be 0.
261 * On exit, the RETURN REGISTER contains the value of the C
262 * library errno variable.
264 semihosting->result = semihosting->sys_errno;
267 case SEMIHOSTING_SYS_EXIT: /* 0x18 */
269 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
270 * previous versions of the documentation.
272 * An application calls this operation to report an exception
273 * to the debugger directly. The most common use is to report
274 * that execution has completed, using ADP_Stopped_ApplicationExit.
276 * Note: This semihosting operation provides no means for 32-bit
277 * callers to indicate an application exit with a specified exit
278 * code. Semihosting callers may prefer to check for the presence
279 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
280 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
284 * On entry, the PARAMETER register is set to a reason code
285 * describing the cause of the trap. Not all semihosting client
286 * implementations will necessarily trap every corresponding
287 * event. Important reason codes are:
289 * - ADP_Stopped_ApplicationExit 0x20026
290 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
293 * On entry, the PARAMETER REGISTER contains a pointer to a
294 * two-field argument block:
295 * - field 1 The exception type, which is one of the set of
296 * reason codes in the above tables.
297 * - field 2 A subcode, whose meaning depends on the reason
299 * In particular, if field 1 is ADP_Stopped_ApplicationExit
300 * then field 2 is an exit status code, as passed to the C
301 * standard library exit() function. A simulator receiving
302 * this request must notify a connected debugger, if present,
303 * and then exit with the specified status.
306 * No return is expected from these calls. However, it is
307 * possible for the debugger to request that the application
308 * continues by performing an RDI_Execute request or equivalent.
309 * In this case, execution continues with the registers as they
310 * were on entry to the operation, or as subsequently modified
313 if (semihosting->word_size_bytes == 8) {
314 retval = semihosting_read_fields(target, 2, fields);
315 if (retval != ERROR_OK)
318 int type = semihosting_get_field(target, 0, fields);
319 int code = semihosting_get_field(target, 1, fields);
321 if (type == ADP_STOPPED_APPLICATION_EXIT) {
322 if (!gdb_actual_connections)
326 "semihosting: *** application exited with %d ***\n",
331 "semihosting: application exception %#x\n",
336 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
337 if (!gdb_actual_connections)
341 "semihosting: *** application exited normally ***\n");
343 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
344 /* Chosen more or less arbitrarly to have a nicer message,
345 * otherwise all other return the same exit code 1. */
346 if (!gdb_actual_connections)
350 "semihosting: *** application exited with error ***\n");
353 if (!gdb_actual_connections)
357 "semihosting: application exception %#x\n",
358 (unsigned) semihosting->param);
362 if (!semihosting->has_resumable_exit) {
363 semihosting->is_resumable = false;
364 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
368 case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
370 * This operation is only supported if the semihosting extension
371 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
372 * reported using feature byte 0, bit 0. If this extension is
373 * supported, then the implementation provides a means to
374 * report a normal exit with a nonzero exit status in both 32-bit
375 * and 64-bit semihosting APIs.
377 * The implementation must provide the semihosting call
378 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
380 * SYS_EXIT_EXTENDED is used by an application to report an
381 * exception or exit to the debugger directly. The most common
382 * use is to report that execution has completed, using
383 * ADP_Stopped_ApplicationExit.
386 * On entry, the PARAMETER REGISTER contains a pointer to a
387 * two-field argument block:
388 * - field 1 The exception type, which should be one of the set
389 * of reason codes that are documented for the SYS_EXIT
390 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
391 * - field 2 A subcode, whose meaning depends on the reason
392 * code in field 1. In particular, if field 1 is
393 * ADP_Stopped_ApplicationExit then field 2 is an exit status
394 * code, as passed to the C standard library exit() function.
395 * A simulator receiving this request must notify a connected
396 * debugger, if present, and then exit with the specified status.
399 * No return is expected from these calls.
401 * For the A64 API, this call is identical to the behavior of
402 * the mandatory SYS_EXIT (0x18) call. If this extension is
403 * supported, then both calls must be implemented.
405 retval = semihosting_read_fields(target, 2, fields);
406 if (retval != ERROR_OK)
409 int type = semihosting_get_field(target, 0, fields);
410 int code = semihosting_get_field(target, 1, fields);
412 if (type == ADP_STOPPED_APPLICATION_EXIT) {
413 if (!gdb_actual_connections)
417 "semihosting: *** application exited with %d ***\n",
421 fprintf(stderr, "semihosting: exception %#x\n",
425 if (!semihosting->has_resumable_exit) {
426 semihosting->is_resumable = false;
427 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
431 case SEMIHOSTING_SYS_FLEN: /* 0x0C */
433 * Returns the length of a specified file.
436 * On entry, the PARAMETER REGISTER contains a pointer to a
437 * one-field argument block:
438 * - field 1 A handle for a previously opened, seekable file
442 * On exit, the RETURN REGISTER contains:
443 * - The current length of the file object, if the call is
445 * - –1 if an error occurs.
447 if (semihosting->is_fileio) {
448 LOG_ERROR("SYS_FLEN not supported by semihosting fileio");
451 retval = semihosting_read_fields(target, 1, fields);
452 if (retval != ERROR_OK)
455 int fd = semihosting_get_field(target, 0, fields);
457 semihosting->result = fstat(fd, &buf);
458 if (semihosting->result == -1) {
459 semihosting->sys_errno = errno;
460 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
463 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
464 semihosting->result = buf.st_size;
468 case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
470 * Returns the command line that is used for the call to the
471 * executable, that is, argc and argv.
474 * On entry, the PARAMETER REGISTER points to a two-field data
475 * block to be used for returning the command string and its length:
476 * - field 1 A pointer to a buffer of at least the size that is
477 * specified in field 2.
478 * - field 2 The length of the buffer in bytes.
482 * If the call is successful, then the RETURN REGISTER contains 0,
483 * the PARAMETER REGISTER is unchanged, and the data block is
484 * updated as follows:
485 * - field 1 A pointer to a null-terminated string of the command
487 * - field 2 The length of the string in bytes.
488 * If the call is not successful, then the RETURN REGISTER
491 * Note: The semihosting implementation might impose limits on
492 * the maximum length of the string that can be transferred.
493 * However, the implementation must be able to support a
494 * command-line length of at least 80 bytes.
496 retval = semihosting_read_fields(target, 2, fields);
497 if (retval != ERROR_OK)
500 uint64_t addr = semihosting_get_field(target, 0, fields);
501 size_t size = semihosting_get_field(target, 1, fields);
503 char *arg = semihosting->cmdline != NULL ?
504 semihosting->cmdline : "";
505 uint32_t len = strlen(arg) + 1;
507 semihosting->result = -1;
509 semihosting_set_field(target, len, 1, fields);
510 retval = target_write_buffer(target, addr, len,
512 if (retval != ERROR_OK)
514 semihosting->result = 0;
516 retval = semihosting_write_fields(target, 2, fields);
517 if (retval != ERROR_OK)
520 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
521 (int)semihosting->result);
525 case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
527 * Returns the system stack and heap parameters.
530 * On entry, the PARAMETER REGISTER contains the address of a
531 * pointer to a four-field data block. The contents of the data
532 * block are filled by the function. The following C-like
533 * pseudocode describes the layout of the block:
542 * On exit, the PARAMETER REGISTER is unchanged and the data
543 * block has been updated.
545 retval = semihosting_read_fields(target, 1, fields);
546 if (retval != ERROR_OK)
549 uint64_t addr = semihosting_get_field(target, 0, fields);
550 /* tell the remote we have no idea */
551 memset(fields, 0, 4 * semihosting->word_size_bytes);
552 retval = target_write_memory(target, addr, 4,
553 semihosting->word_size_bytes,
555 if (retval != ERROR_OK)
557 semihosting->result = 0;
561 case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
563 * Determines whether the return code from another semihosting
564 * call is an error status or not.
566 * This call is passed a parameter block containing the error
570 * On entry, the PARAMETER REGISTER contains a pointer to a
571 * one-field data block:
572 * - field 1 The required status word to check.
575 * On exit, the RETURN REGISTER contains:
576 * - 0 if the status field is not an error indication
577 * - A nonzero value if the status field is an error indication.
579 retval = semihosting_read_fields(target, 1, fields);
580 if (retval != ERROR_OK)
583 uint64_t code = semihosting_get_field(target, 0, fields);
584 semihosting->result = (code != 0);
587 case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
589 * Checks whether a file is connected to an interactive device.
592 * On entry, the PARAMETER REGISTER contains a pointer to a
593 * one-field argument block:
594 * field 1 A handle for a previously opened file object.
597 * On exit, the RETURN REGISTER contains:
598 * - 1 if the handle identifies an interactive device.
599 * - 0 if the handle identifies a file.
600 * - A value other than 1 or 0 if an error occurs.
602 if (semihosting->is_fileio) {
603 semihosting->hit_fileio = true;
604 fileio_info->identifier = "isatty";
605 fileio_info->param_1 = semihosting->param;
607 retval = semihosting_read_fields(target, 1, fields);
608 if (retval != ERROR_OK)
610 int fd = semihosting_get_field(target, 0, fields);
611 semihosting->result = isatty(fd);
612 LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
616 case SEMIHOSTING_SYS_OPEN: /* 0x01 */
618 * Opens a file on the host system.
620 * The file path is specified either as relative to the current
621 * directory of the host process, or absolute, using the path
622 * conventions of the host operating system.
624 * Semihosting implementations must support opening the special
625 * path name :semihosting-features as part of the semihosting
626 * extensions reporting mechanism.
628 * ARM targets interpret the special path name :tt as meaning
629 * the console input stream, for an open-read or the console
630 * output stream, for an open-write. Opening these streams is
631 * performed as part of the standard startup code for those
632 * applications that reference the C stdio streams. The
633 * semihosting extension SH_EXT_STDOUT_STDERR allows the
634 * semihosting caller to open separate output streams
635 * corresponding to stdout and stderr. This extension is
636 * reported using feature byte 0, bit 1. Use SYS_OPEN with
637 * the special path name :semihosting-features to access the
640 * If this extension is supported, the implementation must
641 * support the following additional semantics to SYS_OPEN:
642 * - If the special path name :tt is opened with an fopen
643 * mode requesting write access (w, wb, w+, or w+b), then
644 * this is a request to open stdout.
645 * - If the special path name :tt is opened with a mode
646 * requesting append access (a, ab, a+, or a+b), then this is
647 * a request to open stderr.
650 * On entry, the PARAMETER REGISTER contains a pointer to a
651 * three-field argument block:
652 * - field 1 A pointer to a null-terminated string containing
653 * a file or device name.
654 * - field 2 An integer that specifies the file opening mode.
655 * - field 3 An integer that gives the length of the string
656 * pointed to by field 1.
658 * The length does not include the terminating null character
659 * that must be present.
662 * On exit, the RETURN REGISTER contains:
663 * - A nonzero handle if the call is successful.
664 * - –1 if the call is not successful.
666 retval = semihosting_read_fields(target, 3, fields);
667 if (retval != ERROR_OK)
670 uint64_t addr = semihosting_get_field(target, 0, fields);
671 uint32_t mode = semihosting_get_field(target, 1, fields);
672 size_t len = semihosting_get_field(target, 2, fields);
675 semihosting->result = -1;
676 semihosting->sys_errno = EINVAL;
679 uint8_t *fn = malloc(len+1);
681 semihosting->result = -1;
682 semihosting->sys_errno = ENOMEM;
684 retval = target_read_memory(target, addr, 1, len, fn);
685 if (retval != ERROR_OK) {
690 /* TODO: implement the :semihosting-features special file.
692 if (semihosting->is_fileio) {
693 if (strcmp((char *)fn, ":tt") == 0)
694 semihosting->result = 0;
696 semihosting->hit_fileio = true;
697 fileio_info->identifier = "open";
698 fileio_info->param_1 = addr;
699 fileio_info->param_2 = len;
700 fileio_info->param_3 = open_modeflags[mode];
701 fileio_info->param_4 = 0644;
704 if (strcmp((char *)fn, ":tt") == 0) {
706 * - 0-3 ("r") for stdin,
707 * - 4-7 ("w") for stdout,
708 * - 8-11 ("a") for stderr */
710 semihosting->result = dup(
712 semihosting->sys_errno = errno;
713 LOG_DEBUG("dup(STDIN)=%d",
714 (int)semihosting->result);
715 } else if (mode < 8) {
716 semihosting->result = dup(
718 semihosting->sys_errno = errno;
719 LOG_DEBUG("dup(STDOUT)=%d",
720 (int)semihosting->result);
722 semihosting->result = dup(
724 semihosting->sys_errno = errno;
725 LOG_DEBUG("dup(STDERR)=%d",
726 (int)semihosting->result);
729 /* cygwin requires the permission setting
730 * otherwise it will fail to reopen a previously
732 semihosting->result = open((char *)fn,
733 open_modeflags[mode],
735 semihosting->sys_errno = errno;
736 LOG_DEBUG("open('%s')=%d", fn,
737 (int)semihosting->result);
745 case SEMIHOSTING_SYS_READ: /* 0x06 */
747 * Reads the contents of a file into a buffer. The file position
748 * is specified either:
749 * - Explicitly by a SYS_SEEK.
750 * - Implicitly one byte beyond the previous SYS_READ or
753 * The file position is at the start of the file when it is
754 * opened, and is lost when the file is closed. Perform the
755 * file operation as a single action whenever possible. For
756 * example, do not split a read of 16KB into four 4KB chunks
757 * unless there is no alternative.
760 * On entry, the PARAMETER REGISTER contains a pointer to a
761 * three-field data block:
762 * - field 1 Contains a handle for a file previously opened
764 * - field 2 Points to a buffer.
765 * - field 3 Contains the number of bytes to read to the buffer
769 * On exit, the RETURN REGISTER contains the number of bytes not
770 * filled in the buffer (buffer_length - bytes_read) as follows:
771 * - If the RETURN REGISTER is 0, the entire buffer was
772 * successfully filled.
773 * - If the RETURN REGISTER is the same as field 3, no bytes
774 * were read (EOF can be assumed).
775 * - If the RETURN REGISTER contains a value smaller than
776 * field 3, the read succeeded but the buffer was only partly
777 * filled. For interactive devices, this is the most common
780 retval = semihosting_read_fields(target, 3, fields);
781 if (retval != ERROR_OK)
784 int fd = semihosting_get_field(target, 0, fields);
785 uint64_t addr = semihosting_get_field(target, 1, fields);
786 size_t len = semihosting_get_field(target, 2, fields);
787 if (semihosting->is_fileio) {
788 semihosting->hit_fileio = true;
789 fileio_info->identifier = "read";
790 fileio_info->param_1 = fd;
791 fileio_info->param_2 = addr;
792 fileio_info->param_3 = len;
794 uint8_t *buf = malloc(len);
796 semihosting->result = -1;
797 semihosting->sys_errno = ENOMEM;
799 semihosting->result = read(fd, buf, len);
800 semihosting->sys_errno = errno;
801 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
805 (int)semihosting->result);
806 if (semihosting->result >= 0) {
807 retval = target_write_buffer(target, addr,
810 if (retval != ERROR_OK) {
814 /* the number of bytes NOT filled in */
815 semihosting->result = len -
824 case SEMIHOSTING_SYS_READC: /* 0x07 */
826 * Reads a byte from the console.
829 * The PARAMETER REGISTER must contain 0. There are no other
830 * parameters or values possible.
833 * On exit, the RETURN REGISTER contains the byte read from
836 if (semihosting->is_fileio) {
837 LOG_ERROR("SYS_READC not supported by semihosting fileio");
840 semihosting->result = getchar();
841 LOG_DEBUG("getchar()=%d", (int)semihosting->result);
844 case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
846 * Deletes a specified file on the host filing system.
849 * On entry, the PARAMETER REGISTER contains a pointer to a
850 * two-field argument block:
851 * - field 1 Points to a null-terminated string that gives the
852 * path name of the file to be deleted.
853 * - field 2 The length of the string.
856 * On exit, the RETURN REGISTER contains:
857 * - 0 if the delete is successful
858 * - A nonzero, host-specific error code if the delete fails.
860 retval = semihosting_read_fields(target, 2, fields);
861 if (retval != ERROR_OK)
864 uint64_t addr = semihosting_get_field(target, 0, fields);
865 size_t len = semihosting_get_field(target, 1, fields);
866 if (semihosting->is_fileio) {
867 semihosting->hit_fileio = true;
868 fileio_info->identifier = "unlink";
869 fileio_info->param_1 = addr;
870 fileio_info->param_2 = len;
872 uint8_t *fn = malloc(len+1);
874 semihosting->result = -1;
875 semihosting->sys_errno = ENOMEM;
878 target_read_memory(target, addr, 1, len,
880 if (retval != ERROR_OK) {
885 semihosting->result = remove((char *)fn);
886 semihosting->sys_errno = errno;
887 LOG_DEBUG("remove('%s')=%d", fn,
888 (int)semihosting->result);
896 case SEMIHOSTING_SYS_RENAME: /* 0x0F */
898 * Renames a specified file.
901 * On entry, the PARAMETER REGISTER contains a pointer to a
902 * four-field data block:
903 * - field 1 A pointer to the name of the old file.
904 * - field 2 The length of the old filename.
905 * - field 3 A pointer to the new filename.
906 * - field 4 The length of the new filename. Both strings are
910 * On exit, the RETURN REGISTER contains:
911 * - 0 if the rename is successful.
912 * - A nonzero, host-specific error code if the rename fails.
914 retval = semihosting_read_fields(target, 4, fields);
915 if (retval != ERROR_OK)
918 uint64_t addr1 = semihosting_get_field(target, 0, fields);
919 size_t len1 = semihosting_get_field(target, 1, fields);
920 uint64_t addr2 = semihosting_get_field(target, 2, fields);
921 size_t len2 = semihosting_get_field(target, 3, fields);
922 if (semihosting->is_fileio) {
923 semihosting->hit_fileio = true;
924 fileio_info->identifier = "rename";
925 fileio_info->param_1 = addr1;
926 fileio_info->param_2 = len1;
927 fileio_info->param_3 = addr2;
928 fileio_info->param_4 = len2;
930 uint8_t *fn1 = malloc(len1+1);
931 uint8_t *fn2 = malloc(len2+1);
933 semihosting->result = -1;
934 semihosting->sys_errno = ENOMEM;
936 retval = target_read_memory(target, addr1, 1, len1,
938 if (retval != ERROR_OK) {
943 retval = target_read_memory(target, addr2, 1, len2,
945 if (retval != ERROR_OK) {
952 semihosting->result = rename((char *)fn1,
954 semihosting->sys_errno = errno;
955 LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
956 (int)semihosting->result);
965 case SEMIHOSTING_SYS_SEEK: /* 0x0A */
967 * Seeks to a specified position in a file using an offset
968 * specified from the start of the file. The file is assumed
969 * to be a byte array and the offset is given in bytes.
972 * On entry, the PARAMETER REGISTER contains a pointer to a
973 * two-field data block:
974 * - field 1 A handle for a seekable file object.
975 * - field 2 The absolute byte position to seek to.
978 * On exit, the RETURN REGISTER contains:
979 * - 0 if the request is successful.
980 * - A negative value if the request is not successful.
981 * Use SYS_ERRNO to read the value of the host errno variable
982 * describing the error.
984 * Note: The effect of seeking outside the current extent of
985 * the file object is undefined.
987 retval = semihosting_read_fields(target, 2, fields);
988 if (retval != ERROR_OK)
991 int fd = semihosting_get_field(target, 0, fields);
992 off_t pos = semihosting_get_field(target, 1, fields);
993 if (semihosting->is_fileio) {
994 semihosting->hit_fileio = true;
995 fileio_info->identifier = "lseek";
996 fileio_info->param_1 = fd;
997 fileio_info->param_2 = pos;
998 fileio_info->param_3 = SEEK_SET;
1000 semihosting->result = lseek(fd, pos, SEEK_SET);
1001 semihosting->sys_errno = errno;
1002 LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
1003 (int)semihosting->result);
1004 if (semihosting->result == pos)
1005 semihosting->result = 0;
1010 case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
1012 * Passes a command to the host command-line interpreter.
1013 * This enables you to execute a system command such as dir,
1014 * ls, or pwd. The terminal I/O is on the host, and is not
1015 * visible to the target.
1018 * On entry, the PARAMETER REGISTER contains a pointer to a
1019 * two-field argument block:
1020 * - field 1 Points to a string to be passed to the host
1021 * command-line interpreter.
1022 * - field 2 The length of the string.
1025 * On exit, the RETURN REGISTER contains the return status.
1028 /* Provide SYS_SYSTEM functionality. Uses the
1029 * libc system command, there may be a reason *NOT*
1030 * to use this, but as I can't think of one, I
1031 * implemented it this way.
1033 retval = semihosting_read_fields(target, 2, fields);
1034 if (retval != ERROR_OK)
1037 uint64_t addr = semihosting_get_field(target, 0, fields);
1038 size_t len = semihosting_get_field(target, 1, fields);
1039 if (semihosting->is_fileio) {
1040 semihosting->hit_fileio = true;
1041 fileio_info->identifier = "system";
1042 fileio_info->param_1 = addr;
1043 fileio_info->param_2 = len;
1045 uint8_t *cmd = malloc(len+1);
1047 semihosting->result = -1;
1048 semihosting->sys_errno = ENOMEM;
1050 retval = target_read_memory(target,
1055 if (retval != ERROR_OK) {
1060 semihosting->result = system(
1062 LOG_DEBUG("system('%s')=%d",
1064 (int)semihosting->result);
1073 case SEMIHOSTING_SYS_TIME: /* 0x11 */
1075 * Returns the number of seconds since 00:00 January 1, 1970.
1076 * This value is real-world time, regardless of any debug agent
1080 * There are no parameters.
1083 * On exit, the RETURN REGISTER contains the number of seconds.
1085 semihosting->result = time(NULL);
1088 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1090 * Writes the contents of a buffer to a specified file at the
1091 * current file position. The file position is specified either:
1092 * - Explicitly, by a SYS_SEEK.
1093 * - Implicitly as one byte beyond the previous SYS_READ or
1094 * SYS_WRITE request.
1096 * The file position is at the start of the file when the file
1097 * is opened, and is lost when the file is closed.
1099 * Perform the file operation as a single action whenever
1100 * possible. For example, do not split a write of 16KB into
1101 * four 4KB chunks unless there is no alternative.
1104 * On entry, the PARAMETER REGISTER contains a pointer to a
1105 * three-field data block:
1106 * - field 1 Contains a handle for a file previously opened
1108 * - field 2 Points to the memory containing the data to be written.
1109 * - field 3 Contains the number of bytes to be written from
1110 * the buffer to the file.
1113 * On exit, the RETURN REGISTER contains:
1114 * - 0 if the call is successful.
1115 * - The number of bytes that are not written, if there is an error.
1117 retval = semihosting_read_fields(target, 3, fields);
1118 if (retval != ERROR_OK)
1121 int fd = semihosting_get_field(target, 0, fields);
1122 uint64_t addr = semihosting_get_field(target, 1, fields);
1123 size_t len = semihosting_get_field(target, 2, fields);
1124 if (semihosting->is_fileio) {
1125 semihosting->hit_fileio = true;
1126 fileio_info->identifier = "write";
1127 fileio_info->param_1 = fd;
1128 fileio_info->param_2 = addr;
1129 fileio_info->param_3 = len;
1131 uint8_t *buf = malloc(len);
1133 semihosting->result = -1;
1134 semihosting->sys_errno = ENOMEM;
1136 retval = target_read_buffer(target, addr, len, buf);
1137 if (retval != ERROR_OK) {
1141 semihosting->result = write(fd, buf, len);
1142 semihosting->sys_errno = errno;
1143 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
1147 (int)semihosting->result);
1148 if (semihosting->result >= 0) {
1149 /* The number of bytes that are NOT written.
1151 semihosting->result = len -
1152 semihosting->result;
1161 case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
1163 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1164 * to the debug channel. When executed under a semihosting
1165 * debugger, the character appears on the host debugger console.
1168 * On entry, the PARAMETER REGISTER contains a pointer to the
1172 * None. The RETURN REGISTER is corrupted.
1174 if (semihosting->is_fileio) {
1175 semihosting->hit_fileio = true;
1176 fileio_info->identifier = "write";
1177 fileio_info->param_1 = 1;
1178 fileio_info->param_2 = semihosting->param;
1179 fileio_info->param_3 = 1;
1181 uint64_t addr = semihosting->param;
1183 retval = target_read_memory(target, addr, 1, 1, &c);
1184 if (retval != ERROR_OK)
1187 semihosting->result = 0;
1191 case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
1193 * Writes a null-terminated string to the debug channel.
1194 * When executed under a semihosting debugger, the characters
1195 * appear on the host debugger console.
1198 * On entry, the PARAMETER REGISTER contains a pointer to the
1199 * first byte of the string.
1202 * None. The RETURN REGISTER is corrupted.
1204 if (semihosting->is_fileio) {
1206 uint64_t addr = semihosting->param;
1209 retval = target_read_memory(target, addr, 1, 1, &c);
1210 if (retval != ERROR_OK)
1216 semihosting->hit_fileio = true;
1217 fileio_info->identifier = "write";
1218 fileio_info->param_1 = 1;
1219 fileio_info->param_2 = semihosting->param;
1220 fileio_info->param_3 = count;
1222 uint64_t addr = semihosting->param;
1225 retval = target_read_memory(target, addr++, 1, 1, &c);
1226 if (retval != ERROR_OK)
1232 semihosting->result = 0;
1236 case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
1238 * Returns the number of elapsed target ticks since execution
1240 * Use SYS_TICKFREQ to determine the tick frequency.
1243 * On entry, the PARAMETER REGISTER points to a two-field data
1244 * block to be used for returning the number of elapsed ticks:
1245 * - field 1 The least significant field and is at the low address.
1246 * - field 2 The most significant field and is at the high address.
1249 * On entry the PARAMETER REGISTER points to a one-field data
1250 * block to be used for returning the number of elapsed ticks:
1251 * - field 1 The number of elapsed ticks as a 64-bit value.
1255 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1256 * REGISTER is unchanged, and the data block pointed to by the
1257 * PARAMETER REGISTER is filled in with the number of elapsed
1259 * - On failure, the RETURN REGISTER contains -1, and the
1260 * PARAMETER REGISTER contains -1.
1262 * Note: Some semihosting implementations might not support this
1263 * semihosting operation, and they always return -1 in the
1267 case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
1269 * Returns the tick frequency.
1272 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1275 * On exit, the RETURN REGISTER contains either:
1276 * - The number of ticks per second.
1277 * - –1 if the target does not know the value of one tick.
1279 * Note: Some semihosting implementations might not support
1280 * this semihosting operation, and they always return -1 in the
1284 case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
1286 * Returns a temporary name for a file identified by a system
1290 * On entry, the PARAMETER REGISTER contains a pointer to a
1291 * three-word argument block:
1292 * - field 1 A pointer to a buffer.
1293 * - field 2 A target identifier for this filename. Its value
1294 * must be an integer in the range 0-255.
1295 * - field 3 Contains the length of the buffer. The length must
1296 * be at least the value of L_tmpnam on the host system.
1299 * On exit, the RETURN REGISTER contains:
1300 * - 0 if the call is successful.
1301 * - –1 if an error occurs.
1303 * The buffer pointed to by the PARAMETER REGISTER contains
1304 * the filename, prefixed with a suitable directory name.
1305 * If you use the same target identifier again, the same
1306 * filename is returned.
1308 * Note: The returned string must be null-terminated.
1312 fprintf(stderr, "semihosting: unsupported call %#x\n",
1313 (unsigned) semihosting->op);
1314 semihosting->result = -1;
1315 semihosting->sys_errno = ENOTSUP;
1318 if (!semihosting->hit_fileio) {
1319 retval = semihosting->post_result(target);
1320 if (retval != ERROR_OK) {
1321 LOG_ERROR("Failed to post semihosting result");
1329 /* -------------------------------------------------------------------------
1330 * Local functions. */
1332 static int semihosting_common_fileio_info(struct target *target,
1333 struct gdb_fileio_info *fileio_info)
1335 struct semihosting *semihosting = target->semihosting;
1340 * To avoid unnecessary duplication, semihosting prepares the
1341 * fileio_info structure out-of-band when the target halts. See
1342 * do_semihosting for more detail.
1344 if (!semihosting->is_fileio || !semihosting->hit_fileio)
1350 static int semihosting_common_fileio_end(struct target *target, int result,
1351 int fileio_errno, bool ctrl_c)
1353 struct gdb_fileio_info *fileio_info = target->fileio_info;
1354 struct semihosting *semihosting = target->semihosting;
1358 /* clear pending status */
1359 semihosting->hit_fileio = false;
1361 semihosting->result = result;
1362 semihosting->sys_errno = fileio_errno;
1365 * Some fileio results do not match up with what the semihosting
1366 * operation expects; for these operations, we munge the results
1369 switch (semihosting->op) {
1370 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1372 semihosting->result = fileio_info->param_3;
1374 semihosting->result = 0;
1377 case SEMIHOSTING_SYS_READ: /* 0x06 */
1378 if (result == (int)fileio_info->param_3)
1379 semihosting->result = 0;
1381 semihosting->result = fileio_info->param_3;
1384 case SEMIHOSTING_SYS_SEEK: /* 0x0a */
1386 semihosting->result = 0;
1390 return semihosting->post_result(target);
1394 * Read all fields of a command from target to buffer.
1396 static int semihosting_read_fields(struct target *target, size_t number,
1399 struct semihosting *semihosting = target->semihosting;
1400 return target_read_memory(target, semihosting->param,
1401 semihosting->word_size_bytes, number, fields);
1405 * Write all fields of a command from buffer to target.
1407 static int semihosting_write_fields(struct target *target, size_t number,
1410 struct semihosting *semihosting = target->semihosting;
1411 return target_write_memory(target, semihosting->param,
1412 semihosting->word_size_bytes, number, fields);
1416 * Extract a field from the buffer, considering register size and endianness.
1418 static uint64_t semihosting_get_field(struct target *target, size_t index,
1421 struct semihosting *semihosting = target->semihosting;
1422 if (semihosting->word_size_bytes == 8)
1423 return target_buffer_get_u64(target, fields + (index * 8));
1425 return target_buffer_get_u32(target, fields + (index * 4));
1429 * Store a field in the buffer, considering register size and endianness.
1431 static void semihosting_set_field(struct target *target, uint64_t value,
1435 struct semihosting *semihosting = target->semihosting;
1436 if (semihosting->word_size_bytes == 8)
1437 target_buffer_set_u64(target, fields + (index * 8), value);
1439 target_buffer_set_u32(target, fields + (index * 4), value);
1443 /* -------------------------------------------------------------------------
1444 * Common semihosting commands handlers. */
1446 __COMMAND_HANDLER(handle_common_semihosting_command)
1448 struct target *target = get_current_target(CMD_CTX);
1450 if (target == NULL) {
1451 LOG_ERROR("No target selected");
1455 struct semihosting *semihosting = target->semihosting;
1457 command_print(CMD_CTX, "semihosting not supported for current target");
1464 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1466 if (!target_was_examined(target)) {
1467 LOG_ERROR("Target not examined yet");
1471 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1472 LOG_ERROR("Failed to Configure semihosting");
1476 /* FIXME never let that "catch" be dropped! (???) */
1477 semihosting->is_active = is_active;
1480 command_print(CMD_CTX, "semihosting is %s",
1481 semihosting->is_active
1482 ? "enabled" : "disabled");
1488 __COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1490 struct target *target = get_current_target(CMD_CTX);
1492 if (target == NULL) {
1493 LOG_ERROR("No target selected");
1497 struct semihosting *semihosting = target->semihosting;
1499 command_print(CMD_CTX, "semihosting not supported for current target");
1503 if (!semihosting->is_active) {
1504 command_print(CMD_CTX, "semihosting not yet enabled for current target");
1509 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1511 command_print(CMD_CTX, "semihosting fileio is %s",
1512 semihosting->is_fileio
1513 ? "enabled" : "disabled");
1518 __COMMAND_HANDLER(handle_common_semihosting_cmdline)
1520 struct target *target = get_current_target(CMD_CTX);
1523 if (target == NULL) {
1524 LOG_ERROR("No target selected");
1528 struct semihosting *semihosting = target->semihosting;
1530 command_print(CMD_CTX, "semihosting not supported for current target");
1534 free(semihosting->cmdline);
1535 semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1537 for (i = 1; i < CMD_ARGC; i++) {
1538 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1539 if (cmdline == NULL)
1541 free(semihosting->cmdline);
1542 semihosting->cmdline = cmdline;
1545 command_print(CMD_CTX, "semihosting command line is [%s]",
1546 semihosting->cmdline);
1551 __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1553 struct target *target = get_current_target(CMD_CTX);
1555 if (target == NULL) {
1556 LOG_ERROR("No target selected");
1560 struct semihosting *semihosting = target->semihosting;
1562 command_print(CMD_CTX, "semihosting not supported for current target");
1566 if (!semihosting->is_active) {
1567 command_print(CMD_CTX, "semihosting not yet enabled for current target");
1572 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
1574 command_print(CMD_CTX, "semihosting resumable exit is %s",
1575 semihosting->has_resumable_exit
1576 ? "enabled" : "disabled");