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_gdb_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 const int open_host_modeflags[12] = {
91 O_WRONLY | O_CREAT | O_TRUNC,
92 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
93 O_RDWR | O_CREAT | O_TRUNC,
94 O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
95 O_WRONLY | O_CREAT | O_APPEND,
96 O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
97 O_RDWR | O_CREAT | O_APPEND,
98 O_RDWR | O_CREAT | O_APPEND | O_BINARY
101 static int semihosting_common_fileio_info(struct target *target,
102 struct gdb_fileio_info *fileio_info);
103 static int semihosting_common_fileio_end(struct target *target, int result,
104 int fileio_errno, bool ctrl_c);
106 /* Attempts to include gdb_server.h failed. */
107 extern int gdb_actual_connections;
110 * Initialize common semihosting support.
112 * @param target Pointer to the target to initialize.
115 * @return An error status if there is a problem during initialization.
117 int semihosting_common_init(struct target *target, void *setup,
122 target->fileio_info = malloc(sizeof(*target->fileio_info));
123 if (!target->fileio_info) {
124 LOG_ERROR("out of memory");
127 memset(target->fileio_info, 0, sizeof(*target->fileio_info));
129 struct semihosting *semihosting;
130 semihosting = malloc(sizeof(*target->semihosting));
132 LOG_ERROR("out of memory");
136 semihosting->is_active = false;
137 semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
138 semihosting->tcp_connection = NULL;
139 semihosting->stdin_fd = -1;
140 semihosting->stdout_fd = -1;
141 semihosting->stderr_fd = -1;
142 semihosting->is_fileio = false;
143 semihosting->hit_fileio = false;
144 semihosting->is_resumable = false;
145 semihosting->has_resumable_exit = false;
146 semihosting->word_size_bytes = 0;
147 semihosting->op = -1;
148 semihosting->param = 0;
149 semihosting->result = -1;
150 semihosting->sys_errno = -1;
151 semihosting->cmdline = NULL;
152 semihosting->basedir = NULL;
154 /* If possible, update it in setup(). */
155 semihosting->setup_time = clock();
157 semihosting->setup = setup;
158 semihosting->post_result = post_result;
159 semihosting->user_command_extension = NULL;
161 target->semihosting = semihosting;
163 target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
164 target->type->gdb_fileio_end = semihosting_common_fileio_end;
169 struct semihosting_tcp_service {
170 struct semihosting *semihosting;
175 static bool semihosting_is_redirected(struct semihosting *semihosting, int fd)
177 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_NONE)
180 bool is_read_op = false;
182 switch (semihosting->op) {
183 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
184 case SEMIHOSTING_SYS_READC:
187 case SEMIHOSTING_SYS_WRITEC:
188 case SEMIHOSTING_SYS_WRITE0:
189 /* debug operations are redirected when CFG is either DEBUG or ALL */
190 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_STDIO)
194 /* check stdio semihosting operations: READ and WRITE */
195 case SEMIHOSTING_SYS_READ:
198 case SEMIHOSTING_SYS_WRITE:
199 /* stdio operations are redirected when CFG is either STDIO or ALL */
200 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_DEBUG)
209 return fd == semihosting->stdin_fd;
211 /* write operation */
212 return fd == semihosting->stdout_fd || fd == semihosting->stderr_fd;
215 static ssize_t semihosting_redirect_write(struct semihosting *semihosting, void *buf, int size)
217 if (!semihosting->tcp_connection) {
218 LOG_ERROR("No connected TCP client for semihosting");
219 semihosting->sys_errno = EBADF; /* Bad file number */
223 struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
225 int retval = connection_write(semihosting->tcp_connection, buf, size);
228 log_socket_error(service->name);
233 static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void *buf, int size)
235 if (semihosting_is_redirected(semihosting, fd))
236 return semihosting_redirect_write(semihosting, buf, size);
239 return write(fd, buf, size);
242 static ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size)
244 if (!semihosting->tcp_connection) {
245 LOG_ERROR("No connected TCP client for semihosting");
246 semihosting->sys_errno = EBADF; /* Bad file number */
250 struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
252 service->error = ERROR_OK;
253 semihosting->tcp_connection->input_pending = true;
255 int retval = connection_read(semihosting->tcp_connection, buf, size);
258 service->error = ERROR_SERVER_REMOTE_CLOSED;
261 log_socket_error(service->name);
263 semihosting->tcp_connection->input_pending = false;
268 static inline int semihosting_putchar(struct semihosting *semihosting, int fd, int c)
270 if (semihosting_is_redirected(semihosting, fd))
271 return semihosting_redirect_write(semihosting, &c, 1);
273 /* default putchar */
277 static inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, void *buf, int size)
279 if (semihosting_is_redirected(semihosting, fd))
280 return semihosting_redirect_read(semihosting, buf, size);
283 ssize_t result = read(fd, buf, size);
284 semihosting->sys_errno = errno;
289 static inline int semihosting_getchar(struct semihosting *semihosting, int fd)
291 if (semihosting_is_redirected(semihosting, fd)) {
294 if (semihosting_redirect_read(semihosting, &c, 1) > 0)
300 /* default getchar */
305 * User operation parameter string storage buffer. Contains valid data when the
306 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
308 static char *semihosting_user_op_params;
311 * Portable implementation of ARM semihosting calls.
312 * Performs the currently pending semihosting operation
313 * encoded in target->semihosting.
315 int semihosting_common(struct target *target)
317 struct semihosting *semihosting = target->semihosting;
319 /* Silently ignore if the semihosting field was not set. */
323 struct gdb_fileio_info *fileio_info = target->fileio_info;
326 * By default return an error.
327 * The actual result must be set by each function
329 semihosting->result = -1;
331 /* Most operations are resumable, except the two exit calls. */
332 semihosting->is_resumable = true;
336 /* Enough space to hold 4 long words. */
339 LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op,
342 switch (semihosting->op) {
344 case SEMIHOSTING_SYS_CLOCK: /* 0x10 */
346 * Returns the number of centiseconds (hundredths of a second)
347 * since the execution started.
349 * Values returned can be of limited use for some benchmarking
350 * purposes because of communication overhead or other
351 * agent-specific factors. For example, with a debug hardware
352 * unit the request is passed back to the host for execution.
353 * This can lead to unpredictable delays in transmission and
354 * process scheduling.
356 * Use this function to calculate time intervals, by calculating
357 * differences between intervals with and without the code
358 * sequence to be timed.
361 * The PARAMETER REGISTER must contain 0. There are no other
365 * On exit, the RETURN REGISTER contains:
366 * - The number of centiseconds since some arbitrary start
367 * point, if the call is successful.
368 * - –1 if the call is not successful. For example, because
369 * of a communications error.
372 clock_t delta = clock() - semihosting->setup_time;
374 semihosting->result = delta / (CLOCKS_PER_SEC / 100);
378 case SEMIHOSTING_SYS_CLOSE: /* 0x02 */
380 * Closes a file on the host system. The handle must reference
381 * a file that was opened with SYS_OPEN.
384 * On entry, the PARAMETER REGISTER contains a pointer to a
385 * one-field argument block:
386 * - field 1 Contains a handle for an open file.
389 * On exit, the RETURN REGISTER contains:
390 * - 0 if the call is successful
391 * - –1 if the call is not successful.
393 retval = semihosting_read_fields(target, 1, fields);
394 if (retval != ERROR_OK)
397 int fd = semihosting_get_field(target, 0, fields);
398 /* Do not allow to close OpenOCD's own standard streams */
399 if (fd == 0 || fd == 1 || fd == 2) {
400 LOG_DEBUG("ignoring semihosting attempt to close %s",
401 (fd == 0) ? "stdin" :
402 (fd == 1) ? "stdout" : "stderr");
403 /* Just pretend success */
404 if (semihosting->is_fileio) {
405 semihosting->result = 0;
407 semihosting->result = 0;
408 semihosting->sys_errno = 0;
412 /* Close the descriptor */
413 if (semihosting->is_fileio) {
414 semihosting->hit_fileio = true;
415 fileio_info->identifier = "close";
416 fileio_info->param_1 = fd;
418 semihosting->result = close(fd);
419 semihosting->sys_errno = errno;
420 LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
425 case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
427 * Returns the value of the C library errno variable that is
428 * associated with the semihosting implementation. The errno
429 * variable can be set by a number of C library semihosted
430 * functions, including:
438 * Whether errno is set or not, and to what value, is entirely
439 * host-specific, except where the ISO C standard defines the
443 * There are no parameters. The PARAMETER REGISTER must be 0.
446 * On exit, the RETURN REGISTER contains the value of the C
447 * library errno variable.
449 semihosting->result = semihosting->sys_errno;
452 case SEMIHOSTING_SYS_EXIT: /* 0x18 */
454 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
455 * previous versions of the documentation.
457 * An application calls this operation to report an exception
458 * to the debugger directly. The most common use is to report
459 * that execution has completed, using ADP_Stopped_ApplicationExit.
461 * Note: This semihosting operation provides no means for 32-bit
462 * callers to indicate an application exit with a specified exit
463 * code. Semihosting callers may prefer to check for the presence
464 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
465 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
469 * On entry, the PARAMETER register is set to a reason code
470 * describing the cause of the trap. Not all semihosting client
471 * implementations will necessarily trap every corresponding
472 * event. Important reason codes are:
474 * - ADP_Stopped_ApplicationExit 0x20026
475 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
478 * On entry, the PARAMETER REGISTER contains a pointer to a
479 * two-field argument block:
480 * - field 1 The exception type, which is one of the set of
481 * reason codes in the above tables.
482 * - field 2 A subcode, whose meaning depends on the reason
484 * In particular, if field 1 is ADP_Stopped_ApplicationExit
485 * then field 2 is an exit status code, as passed to the C
486 * standard library exit() function. A simulator receiving
487 * this request must notify a connected debugger, if present,
488 * and then exit with the specified status.
491 * No return is expected from these calls. However, it is
492 * possible for the debugger to request that the application
493 * continues by performing an RDI_Execute request or equivalent.
494 * In this case, execution continues with the registers as they
495 * were on entry to the operation, or as subsequently modified
498 if (semihosting->word_size_bytes == 8) {
499 retval = semihosting_read_fields(target, 2, fields);
500 if (retval != ERROR_OK)
503 int type = semihosting_get_field(target, 0, fields);
504 int code = semihosting_get_field(target, 1, fields);
506 if (type == ADP_STOPPED_APPLICATION_EXIT) {
507 if (!gdb_actual_connections)
511 "semihosting: *** application exited with %d ***\n",
516 "semihosting: application exception %#x\n",
521 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
522 if (!gdb_actual_connections)
526 "semihosting: *** application exited normally ***\n");
528 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
529 /* Chosen more or less arbitrarily to have a nicer message,
530 * otherwise all other return the same exit code 1. */
531 if (!gdb_actual_connections)
535 "semihosting: *** application exited with error ***\n");
538 if (!gdb_actual_connections)
542 "semihosting: application exception %#x\n",
543 (unsigned) semihosting->param);
547 if (!semihosting->has_resumable_exit) {
548 semihosting->is_resumable = false;
549 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
553 case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
555 * This operation is only supported if the semihosting extension
556 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
557 * reported using feature byte 0, bit 0. If this extension is
558 * supported, then the implementation provides a means to
559 * report a normal exit with a nonzero exit status in both 32-bit
560 * and 64-bit semihosting APIs.
562 * The implementation must provide the semihosting call
563 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
565 * SYS_EXIT_EXTENDED is used by an application to report an
566 * exception or exit to the debugger directly. The most common
567 * use is to report that execution has completed, using
568 * ADP_Stopped_ApplicationExit.
571 * On entry, the PARAMETER REGISTER contains a pointer to a
572 * two-field argument block:
573 * - field 1 The exception type, which should be one of the set
574 * of reason codes that are documented for the SYS_EXIT
575 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
576 * - field 2 A subcode, whose meaning depends on the reason
577 * code in field 1. In particular, if field 1 is
578 * ADP_Stopped_ApplicationExit then field 2 is an exit status
579 * code, as passed to the C standard library exit() function.
580 * A simulator receiving this request must notify a connected
581 * debugger, if present, and then exit with the specified status.
584 * No return is expected from these calls.
586 * For the A64 API, this call is identical to the behavior of
587 * the mandatory SYS_EXIT (0x18) call. If this extension is
588 * supported, then both calls must be implemented.
590 retval = semihosting_read_fields(target, 2, fields);
591 if (retval != ERROR_OK)
594 int type = semihosting_get_field(target, 0, fields);
595 int code = semihosting_get_field(target, 1, fields);
597 if (type == ADP_STOPPED_APPLICATION_EXIT) {
598 if (!gdb_actual_connections)
602 "semihosting: *** application exited with %d ***\n",
606 fprintf(stderr, "semihosting: exception %#x\n",
610 if (!semihosting->has_resumable_exit) {
611 semihosting->is_resumable = false;
612 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
616 case SEMIHOSTING_SYS_FLEN: /* 0x0C */
618 * Returns the length of a specified file.
621 * On entry, the PARAMETER REGISTER contains a pointer to a
622 * one-field argument block:
623 * - field 1 A handle for a previously opened, seekable file
627 * On exit, the RETURN REGISTER contains:
628 * - The current length of the file object, if the call is
630 * - –1 if an error occurs.
632 if (semihosting->is_fileio) {
633 semihosting->result = -1;
634 semihosting->sys_errno = EINVAL;
636 retval = semihosting_read_fields(target, 1, fields);
637 if (retval != ERROR_OK)
640 int fd = semihosting_get_field(target, 0, fields);
642 semihosting->result = fstat(fd, &buf);
643 if (semihosting->result == -1) {
644 semihosting->sys_errno = errno;
645 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
648 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
649 semihosting->result = buf.st_size;
653 case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
655 * Returns the command line that is used for the call to the
656 * executable, that is, argc and argv.
659 * On entry, the PARAMETER REGISTER points to a two-field data
660 * block to be used for returning the command string and its length:
661 * - field 1 A pointer to a buffer of at least the size that is
662 * specified in field 2.
663 * - field 2 The length of the buffer in bytes.
667 * If the call is successful, then the RETURN REGISTER contains 0,
668 * the PARAMETER REGISTER is unchanged, and the data block is
669 * updated as follows:
670 * - field 1 A pointer to a null-terminated string of the command
672 * - field 2 The length of the string in bytes.
673 * If the call is not successful, then the RETURN REGISTER
676 * Note: The semihosting implementation might impose limits on
677 * the maximum length of the string that can be transferred.
678 * However, the implementation must be able to support a
679 * command-line length of at least 80 bytes.
681 retval = semihosting_read_fields(target, 2, fields);
682 if (retval != ERROR_OK)
685 uint64_t addr = semihosting_get_field(target, 0, fields);
686 size_t size = semihosting_get_field(target, 1, fields);
688 char *arg = semihosting->cmdline ?
689 semihosting->cmdline : "";
690 uint32_t len = strlen(arg) + 1;
692 semihosting->result = -1;
694 semihosting_set_field(target, len, 1, fields);
695 retval = target_write_buffer(target, addr, len,
697 if (retval != ERROR_OK)
699 semihosting->result = 0;
701 retval = semihosting_write_fields(target, 2, fields);
702 if (retval != ERROR_OK)
705 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
706 (int)semihosting->result);
710 case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
712 * Returns the system stack and heap parameters.
715 * On entry, the PARAMETER REGISTER contains the address of a
716 * pointer to a four-field data block. The contents of the data
717 * block are filled by the function. The following C-like
718 * pseudocode describes the layout of the block:
727 * On exit, the PARAMETER REGISTER is unchanged and the data
728 * block has been updated.
730 retval = semihosting_read_fields(target, 1, fields);
731 if (retval != ERROR_OK)
734 uint64_t addr = semihosting_get_field(target, 0, fields);
735 /* tell the remote we have no idea */
736 memset(fields, 0, 4 * semihosting->word_size_bytes);
737 retval = target_write_memory(target, addr, 4,
738 semihosting->word_size_bytes,
740 if (retval != ERROR_OK)
742 semihosting->result = 0;
746 case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
748 * Determines whether the return code from another semihosting
749 * call is an error status or not.
751 * This call is passed a parameter block containing the error
755 * On entry, the PARAMETER REGISTER contains a pointer to a
756 * one-field data block:
757 * - field 1 The required status word to check.
760 * On exit, the RETURN REGISTER contains:
761 * - 0 if the status field is not an error indication
762 * - A nonzero value if the status field is an error indication.
764 retval = semihosting_read_fields(target, 1, fields);
765 if (retval != ERROR_OK)
768 uint64_t code = semihosting_get_field(target, 0, fields);
769 semihosting->result = (code != 0);
772 case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
774 * Checks whether a file is connected to an interactive device.
777 * On entry, the PARAMETER REGISTER contains a pointer to a
778 * one-field argument block:
779 * field 1 A handle for a previously opened file object.
782 * On exit, the RETURN REGISTER contains:
783 * - 1 if the handle identifies an interactive device.
784 * - 0 if the handle identifies a file.
785 * - A value other than 1 or 0 if an error occurs.
787 if (semihosting->is_fileio) {
788 semihosting->hit_fileio = true;
789 fileio_info->identifier = "isatty";
790 fileio_info->param_1 = semihosting->param;
792 retval = semihosting_read_fields(target, 1, fields);
793 if (retval != ERROR_OK)
795 int fd = semihosting_get_field(target, 0, fields);
796 semihosting->result = isatty(fd);
797 semihosting->sys_errno = errno;
798 LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
802 case SEMIHOSTING_SYS_OPEN: /* 0x01 */
804 * Opens a file on the host system.
806 * The file path is specified either as relative to the current
807 * directory of the host process, or absolute, using the path
808 * conventions of the host operating system.
810 * Semihosting implementations must support opening the special
811 * path name :semihosting-features as part of the semihosting
812 * extensions reporting mechanism.
814 * ARM targets interpret the special path name :tt as meaning
815 * the console input stream, for an open-read or the console
816 * output stream, for an open-write. Opening these streams is
817 * performed as part of the standard startup code for those
818 * applications that reference the C stdio streams. The
819 * semihosting extension SH_EXT_STDOUT_STDERR allows the
820 * semihosting caller to open separate output streams
821 * corresponding to stdout and stderr. This extension is
822 * reported using feature byte 0, bit 1. Use SYS_OPEN with
823 * the special path name :semihosting-features to access the
826 * If this extension is supported, the implementation must
827 * support the following additional semantics to SYS_OPEN:
828 * - If the special path name :tt is opened with an fopen
829 * mode requesting write access (w, wb, w+, or w+b), then
830 * this is a request to open stdout.
831 * - If the special path name :tt is opened with a mode
832 * requesting append access (a, ab, a+, or a+b), then this is
833 * a request to open stderr.
836 * On entry, the PARAMETER REGISTER contains a pointer to a
837 * three-field argument block:
838 * - field 1 A pointer to a null-terminated string containing
839 * a file or device name.
840 * - field 2 An integer that specifies the file opening mode.
841 * - field 3 An integer that gives the length of the string
842 * pointed to by field 1.
844 * The length does not include the terminating null character
845 * that must be present.
848 * On exit, the RETURN REGISTER contains:
849 * - A nonzero handle if the call is successful.
850 * - –1 if the call is not successful.
852 retval = semihosting_read_fields(target, 3, fields);
853 if (retval != ERROR_OK)
856 uint64_t addr = semihosting_get_field(target, 0, fields);
857 uint32_t mode = semihosting_get_field(target, 1, fields);
858 size_t len = semihosting_get_field(target, 2, fields);
861 semihosting->result = -1;
862 semihosting->sys_errno = EINVAL;
865 size_t basedir_len = semihosting->basedir ? strlen(semihosting->basedir) : 0;
866 uint8_t *fn = malloc(basedir_len + len + 2);
868 semihosting->result = -1;
869 semihosting->sys_errno = ENOMEM;
871 if (basedir_len > 0) {
872 strcpy((char *)fn, semihosting->basedir);
873 if (fn[basedir_len - 1] != '/')
874 fn[basedir_len++] = '/';
876 retval = target_read_memory(target, addr, 1, len, fn + basedir_len);
877 if (retval != ERROR_OK) {
881 fn[basedir_len + len] = 0;
882 /* TODO: implement the :semihosting-features special file.
884 if (semihosting->is_fileio) {
885 if (strcmp((char *)fn, ":semihosting-features") == 0) {
886 semihosting->result = -1;
887 semihosting->sys_errno = EINVAL;
888 } else if (strcmp((char *)fn, ":tt") == 0) {
890 semihosting->result = 0;
892 semihosting->result = 1;
894 semihosting->result = 2;
896 semihosting->result = -1;
898 semihosting->hit_fileio = true;
899 fileio_info->identifier = "open";
900 fileio_info->param_1 = addr;
901 fileio_info->param_2 = len;
902 fileio_info->param_3 = open_gdb_modeflags[mode];
903 fileio_info->param_4 = 0644;
906 if (strcmp((char *)fn, ":tt") == 0) {
908 * - 0-3 ("r") for stdin,
909 * - 4-7 ("w") for stdout,
910 * - 8-11 ("a") for stderr */
912 int fd = dup(STDIN_FILENO);
913 semihosting->result = fd;
914 semihosting->stdin_fd = fd;
915 semihosting->sys_errno = errno;
916 LOG_DEBUG("dup(STDIN)=%d",
917 (int)semihosting->result);
918 } else if (mode < 8) {
919 int fd = dup(STDOUT_FILENO);
920 semihosting->result = fd;
921 semihosting->stdout_fd = fd;
922 semihosting->sys_errno = errno;
923 LOG_DEBUG("dup(STDOUT)=%d",
924 (int)semihosting->result);
926 int fd = dup(STDERR_FILENO);
927 semihosting->result = fd;
928 semihosting->stderr_fd = fd;
929 semihosting->sys_errno = errno;
930 LOG_DEBUG("dup(STDERR)=%d",
931 (int)semihosting->result);
934 /* cygwin requires the permission setting
935 * otherwise it will fail to reopen a previously
937 semihosting->result = open((char *)fn,
938 open_host_modeflags[mode],
940 semihosting->sys_errno = errno;
941 LOG_DEBUG("open('%s')=%d", fn,
942 (int)semihosting->result);
950 case SEMIHOSTING_SYS_READ: /* 0x06 */
952 * Reads the contents of a file into a buffer. The file position
953 * is specified either:
954 * - Explicitly by a SYS_SEEK.
955 * - Implicitly one byte beyond the previous SYS_READ or
958 * The file position is at the start of the file when it is
959 * opened, and is lost when the file is closed. Perform the
960 * file operation as a single action whenever possible. For
961 * example, do not split a read of 16KB into four 4KB chunks
962 * unless there is no alternative.
965 * On entry, the PARAMETER REGISTER contains a pointer to a
966 * three-field data block:
967 * - field 1 Contains a handle for a file previously opened
969 * - field 2 Points to a buffer.
970 * - field 3 Contains the number of bytes to read to the buffer
974 * On exit, the RETURN REGISTER contains the number of bytes not
975 * filled in the buffer (buffer_length - bytes_read) as follows:
976 * - If the RETURN REGISTER is 0, the entire buffer was
977 * successfully filled.
978 * - If the RETURN REGISTER is the same as field 3, no bytes
979 * were read (EOF can be assumed).
980 * - If the RETURN REGISTER contains a value smaller than
981 * field 3, the read succeeded but the buffer was only partly
982 * filled. For interactive devices, this is the most common
985 retval = semihosting_read_fields(target, 3, fields);
986 if (retval != ERROR_OK)
989 int fd = semihosting_get_field(target, 0, fields);
990 uint64_t addr = semihosting_get_field(target, 1, fields);
991 size_t len = semihosting_get_field(target, 2, fields);
992 if (semihosting->is_fileio) {
993 semihosting->hit_fileio = true;
994 fileio_info->identifier = "read";
995 fileio_info->param_1 = fd;
996 fileio_info->param_2 = addr;
997 fileio_info->param_3 = len;
999 uint8_t *buf = malloc(len);
1001 semihosting->result = -1;
1002 semihosting->sys_errno = ENOMEM;
1004 semihosting->result = semihosting_read(semihosting, fd, buf, len);
1005 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
1009 (int)semihosting->result);
1010 if (semihosting->result >= 0) {
1011 retval = target_write_buffer(target, addr,
1012 semihosting->result,
1014 if (retval != ERROR_OK) {
1018 /* the number of bytes NOT filled in */
1019 semihosting->result = len -
1020 semihosting->result;
1028 case SEMIHOSTING_SYS_READC: /* 0x07 */
1030 * Reads a byte from the console.
1033 * The PARAMETER REGISTER must contain 0. There are no other
1034 * parameters or values possible.
1037 * On exit, the RETURN REGISTER contains the byte read from
1040 if (semihosting->is_fileio) {
1041 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1044 semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);
1045 LOG_DEBUG("getchar()=%d", (int)semihosting->result);
1048 case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
1050 * Deletes a specified file on the host filing system.
1053 * On entry, the PARAMETER REGISTER contains a pointer to a
1054 * two-field argument block:
1055 * - field 1 Points to a null-terminated string that gives the
1056 * path name of the file to be deleted.
1057 * - field 2 The length of the string.
1060 * On exit, the RETURN REGISTER contains:
1061 * - 0 if the delete is successful
1062 * - A nonzero, host-specific error code if the delete fails.
1064 retval = semihosting_read_fields(target, 2, fields);
1065 if (retval != ERROR_OK)
1068 uint64_t addr = semihosting_get_field(target, 0, fields);
1069 size_t len = semihosting_get_field(target, 1, fields);
1070 if (semihosting->is_fileio) {
1071 semihosting->hit_fileio = true;
1072 fileio_info->identifier = "unlink";
1073 fileio_info->param_1 = addr;
1074 fileio_info->param_2 = len;
1076 uint8_t *fn = malloc(len+1);
1078 semihosting->result = -1;
1079 semihosting->sys_errno = ENOMEM;
1082 target_read_memory(target, addr, 1, len,
1084 if (retval != ERROR_OK) {
1089 semihosting->result = remove((char *)fn);
1090 semihosting->sys_errno = errno;
1091 LOG_DEBUG("remove('%s')=%d", fn,
1092 (int)semihosting->result);
1100 case SEMIHOSTING_SYS_RENAME: /* 0x0F */
1102 * Renames a specified file.
1105 * On entry, the PARAMETER REGISTER contains a pointer to a
1106 * four-field data block:
1107 * - field 1 A pointer to the name of the old file.
1108 * - field 2 The length of the old filename.
1109 * - field 3 A pointer to the new filename.
1110 * - field 4 The length of the new filename. Both strings are
1114 * On exit, the RETURN REGISTER contains:
1115 * - 0 if the rename is successful.
1116 * - A nonzero, host-specific error code if the rename fails.
1118 retval = semihosting_read_fields(target, 4, fields);
1119 if (retval != ERROR_OK)
1122 uint64_t addr1 = semihosting_get_field(target, 0, fields);
1123 size_t len1 = semihosting_get_field(target, 1, fields);
1124 uint64_t addr2 = semihosting_get_field(target, 2, fields);
1125 size_t len2 = semihosting_get_field(target, 3, fields);
1126 if (semihosting->is_fileio) {
1127 semihosting->hit_fileio = true;
1128 fileio_info->identifier = "rename";
1129 fileio_info->param_1 = addr1;
1130 fileio_info->param_2 = len1;
1131 fileio_info->param_3 = addr2;
1132 fileio_info->param_4 = len2;
1134 uint8_t *fn1 = malloc(len1+1);
1135 uint8_t *fn2 = malloc(len2+1);
1139 semihosting->result = -1;
1140 semihosting->sys_errno = ENOMEM;
1142 retval = target_read_memory(target, addr1, 1, len1,
1144 if (retval != ERROR_OK) {
1149 retval = target_read_memory(target, addr2, 1, len2,
1151 if (retval != ERROR_OK) {
1158 semihosting->result = rename((char *)fn1,
1160 semihosting->sys_errno = errno;
1161 LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
1162 (int)semihosting->result);
1171 case SEMIHOSTING_SYS_SEEK: /* 0x0A */
1173 * Seeks to a specified position in a file using an offset
1174 * specified from the start of the file. The file is assumed
1175 * to be a byte array and the offset is given in bytes.
1178 * On entry, the PARAMETER REGISTER contains a pointer to a
1179 * two-field data block:
1180 * - field 1 A handle for a seekable file object.
1181 * - field 2 The absolute byte position to seek to.
1184 * On exit, the RETURN REGISTER contains:
1185 * - 0 if the request is successful.
1186 * - A negative value if the request is not successful.
1187 * Use SYS_ERRNO to read the value of the host errno variable
1188 * describing the error.
1190 * Note: The effect of seeking outside the current extent of
1191 * the file object is undefined.
1193 retval = semihosting_read_fields(target, 2, fields);
1194 if (retval != ERROR_OK)
1197 int fd = semihosting_get_field(target, 0, fields);
1198 off_t pos = semihosting_get_field(target, 1, fields);
1199 if (semihosting->is_fileio) {
1200 semihosting->hit_fileio = true;
1201 fileio_info->identifier = "lseek";
1202 fileio_info->param_1 = fd;
1203 fileio_info->param_2 = pos;
1204 fileio_info->param_3 = SEEK_SET;
1206 semihosting->result = lseek(fd, pos, SEEK_SET);
1207 semihosting->sys_errno = errno;
1208 LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
1209 (int)semihosting->result);
1210 if (semihosting->result == pos)
1211 semihosting->result = 0;
1216 case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
1218 * Passes a command to the host command-line interpreter.
1219 * This enables you to execute a system command such as dir,
1220 * ls, or pwd. The terminal I/O is on the host, and is not
1221 * visible to the target.
1224 * On entry, the PARAMETER REGISTER contains a pointer to a
1225 * two-field argument block:
1226 * - field 1 Points to a string to be passed to the host
1227 * command-line interpreter.
1228 * - field 2 The length of the string.
1231 * On exit, the RETURN REGISTER contains the return status.
1234 /* Provide SYS_SYSTEM functionality. Uses the
1235 * libc system command, there may be a reason *NOT*
1236 * to use this, but as I can't think of one, I
1237 * implemented it this way.
1239 retval = semihosting_read_fields(target, 2, fields);
1240 if (retval != ERROR_OK)
1243 uint64_t addr = semihosting_get_field(target, 0, fields);
1244 size_t len = semihosting_get_field(target, 1, fields);
1245 if (semihosting->is_fileio) {
1246 semihosting->hit_fileio = true;
1247 fileio_info->identifier = "system";
1248 fileio_info->param_1 = addr;
1249 fileio_info->param_2 = len;
1251 uint8_t *cmd = malloc(len+1);
1253 semihosting->result = -1;
1254 semihosting->sys_errno = ENOMEM;
1256 retval = target_read_memory(target,
1261 if (retval != ERROR_OK) {
1266 semihosting->result = system(
1268 LOG_DEBUG("system('%s')=%d",
1270 (int)semihosting->result);
1279 case SEMIHOSTING_SYS_TIME: /* 0x11 */
1281 * Returns the number of seconds since 00:00 January 1, 1970.
1282 * This value is real-world time, regardless of any debug agent
1286 * There are no parameters.
1289 * On exit, the RETURN REGISTER contains the number of seconds.
1291 semihosting->result = time(NULL);
1294 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1296 * Writes the contents of a buffer to a specified file at the
1297 * current file position. The file position is specified either:
1298 * - Explicitly, by a SYS_SEEK.
1299 * - Implicitly as one byte beyond the previous SYS_READ or
1300 * SYS_WRITE request.
1302 * The file position is at the start of the file when the file
1303 * is opened, and is lost when the file is closed.
1305 * Perform the file operation as a single action whenever
1306 * possible. For example, do not split a write of 16KB into
1307 * four 4KB chunks unless there is no alternative.
1310 * On entry, the PARAMETER REGISTER contains a pointer to a
1311 * three-field data block:
1312 * - field 1 Contains a handle for a file previously opened
1314 * - field 2 Points to the memory containing the data to be written.
1315 * - field 3 Contains the number of bytes to be written from
1316 * the buffer to the file.
1319 * On exit, the RETURN REGISTER contains:
1320 * - 0 if the call is successful.
1321 * - The number of bytes that are not written, if there is an error.
1323 retval = semihosting_read_fields(target, 3, fields);
1324 if (retval != ERROR_OK)
1327 int fd = semihosting_get_field(target, 0, fields);
1328 uint64_t addr = semihosting_get_field(target, 1, fields);
1329 size_t len = semihosting_get_field(target, 2, fields);
1330 if (semihosting->is_fileio) {
1331 semihosting->hit_fileio = true;
1332 fileio_info->identifier = "write";
1333 fileio_info->param_1 = fd;
1334 fileio_info->param_2 = addr;
1335 fileio_info->param_3 = len;
1337 uint8_t *buf = malloc(len);
1339 semihosting->result = -1;
1340 semihosting->sys_errno = ENOMEM;
1342 retval = target_read_buffer(target, addr, len, buf);
1343 if (retval != ERROR_OK) {
1347 semihosting->result = semihosting_write(semihosting, fd, buf, len);
1348 semihosting->sys_errno = errno;
1349 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
1353 (int)semihosting->result);
1354 if (semihosting->result >= 0) {
1355 /* The number of bytes that are NOT written.
1357 semihosting->result = len -
1358 semihosting->result;
1367 case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
1369 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1370 * to the debug channel. When executed under a semihosting
1371 * debugger, the character appears on the host debugger console.
1374 * On entry, the PARAMETER REGISTER contains a pointer to the
1378 * None. The RETURN REGISTER is corrupted.
1380 if (semihosting->is_fileio) {
1381 semihosting->hit_fileio = true;
1382 fileio_info->identifier = "write";
1383 fileio_info->param_1 = 1;
1384 fileio_info->param_2 = semihosting->param;
1385 fileio_info->param_3 = 1;
1387 uint64_t addr = semihosting->param;
1389 retval = target_read_memory(target, addr, 1, 1, &c);
1390 if (retval != ERROR_OK)
1392 semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1393 semihosting->result = 0;
1397 case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
1399 * Writes a null-terminated string to the debug channel.
1400 * When executed under a semihosting debugger, the characters
1401 * appear on the host debugger console.
1404 * On entry, the PARAMETER REGISTER contains a pointer to the
1405 * first byte of the string.
1408 * None. The RETURN REGISTER is corrupted.
1410 if (semihosting->is_fileio) {
1412 uint64_t addr = semihosting->param;
1415 retval = target_read_memory(target, addr, 1, 1, &c);
1416 if (retval != ERROR_OK)
1422 semihosting->hit_fileio = true;
1423 fileio_info->identifier = "write";
1424 fileio_info->param_1 = 1;
1425 fileio_info->param_2 = semihosting->param;
1426 fileio_info->param_3 = count;
1428 uint64_t addr = semihosting->param;
1431 retval = target_read_memory(target, addr++, 1, 1, &c);
1432 if (retval != ERROR_OK)
1436 semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1438 semihosting->result = 0;
1442 case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107:
1444 * This is a user defined operation (while user cmds 0x100-0x1ff
1445 * are possible, only 0x100-0x107 are currently implemented).
1447 * Reads the user operation parameters from target, then fires the
1448 * corresponding target event. When the target callbacks returned,
1449 * cleans up the command parameter buffer.
1452 * On entry, the PARAMETER REGISTER contains a pointer to a
1453 * two-field data block:
1454 * - field 1 Contains a pointer to the bound command parameter
1456 * - field 2 Contains the command parameter string length
1459 * On exit, the RETURN REGISTER contains the return status.
1461 if (semihosting->user_command_extension) {
1462 retval = semihosting->user_command_extension(target);
1463 if (retval != ERROR_NOT_IMPLEMENTED)
1465 /* If custom user command not handled, we are looking for the TCL handler */
1468 assert(!semihosting_user_op_params);
1469 retval = semihosting_read_fields(target, 2, fields);
1470 if (retval != ERROR_OK) {
1471 LOG_ERROR("Failed to read fields for user defined command"
1472 " op=0x%x", semihosting->op);
1476 uint64_t addr = semihosting_get_field(target, 0, fields);
1478 size_t len = semihosting_get_field(target, 1, fields);
1479 if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
1480 LOG_ERROR("The maximum length for user defined command "
1481 "parameter is %u, received length is %zu (op=0x%x)",
1482 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
1488 semihosting_user_op_params = malloc(len + 1);
1489 if (!semihosting_user_op_params)
1491 semihosting_user_op_params[len] = 0;
1493 retval = target_read_buffer(target, addr, len,
1494 (uint8_t *)(semihosting_user_op_params));
1495 if (retval != ERROR_OK) {
1496 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1498 free(semihosting_user_op_params);
1499 semihosting_user_op_params = NULL;
1503 target_handle_event(target, semihosting->op);
1504 free(semihosting_user_op_params);
1505 semihosting_user_op_params = NULL;
1506 semihosting->result = 0;
1509 case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
1511 * Returns the number of elapsed target ticks since execution
1513 * Use SYS_TICKFREQ to determine the tick frequency.
1516 * On entry, the PARAMETER REGISTER points to a two-field data
1517 * block to be used for returning the number of elapsed ticks:
1518 * - field 1 The least significant field and is at the low address.
1519 * - field 2 The most significant field and is at the high address.
1522 * On entry the PARAMETER REGISTER points to a one-field data
1523 * block to be used for returning the number of elapsed ticks:
1524 * - field 1 The number of elapsed ticks as a 64-bit value.
1528 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1529 * REGISTER is unchanged, and the data block pointed to by the
1530 * PARAMETER REGISTER is filled in with the number of elapsed
1532 * - On failure, the RETURN REGISTER contains -1, and the
1533 * PARAMETER REGISTER contains -1.
1535 * Note: Some semihosting implementations might not support this
1536 * semihosting operation, and they always return -1 in the
1540 case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
1542 * Returns the tick frequency.
1545 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1548 * On exit, the RETURN REGISTER contains either:
1549 * - The number of ticks per second.
1550 * - –1 if the target does not know the value of one tick.
1552 * Note: Some semihosting implementations might not support
1553 * this semihosting operation, and they always return -1 in the
1557 case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
1559 * Returns a temporary name for a file identified by a system
1563 * On entry, the PARAMETER REGISTER contains a pointer to a
1564 * three-word argument block:
1565 * - field 1 A pointer to a buffer.
1566 * - field 2 A target identifier for this filename. Its value
1567 * must be an integer in the range 0-255.
1568 * - field 3 Contains the length of the buffer. The length must
1569 * be at least the value of L_tmpnam on the host system.
1572 * On exit, the RETURN REGISTER contains:
1573 * - 0 if the call is successful.
1574 * - –1 if an error occurs.
1576 * The buffer pointed to by the PARAMETER REGISTER contains
1577 * the filename, prefixed with a suitable directory name.
1578 * If you use the same target identifier again, the same
1579 * filename is returned.
1581 * Note: The returned string must be null-terminated.
1585 fprintf(stderr, "semihosting: unsupported call %#x\n",
1586 (unsigned) semihosting->op);
1587 semihosting->result = -1;
1588 semihosting->sys_errno = ENOTSUP;
1591 if (!semihosting->hit_fileio) {
1592 retval = semihosting->post_result(target);
1593 if (retval != ERROR_OK) {
1594 LOG_ERROR("Failed to post semihosting result");
1602 /* -------------------------------------------------------------------------
1603 * Local functions. */
1605 static int semihosting_common_fileio_info(struct target *target,
1606 struct gdb_fileio_info *fileio_info)
1608 struct semihosting *semihosting = target->semihosting;
1613 * To avoid unnecessary duplication, semihosting prepares the
1614 * fileio_info structure out-of-band when the target halts. See
1615 * do_semihosting for more detail.
1617 if (!semihosting->is_fileio || !semihosting->hit_fileio)
1623 static int semihosting_common_fileio_end(struct target *target, int result,
1624 int fileio_errno, bool ctrl_c)
1626 struct gdb_fileio_info *fileio_info = target->fileio_info;
1627 struct semihosting *semihosting = target->semihosting;
1631 /* clear pending status */
1632 semihosting->hit_fileio = false;
1634 semihosting->result = result;
1635 semihosting->sys_errno = fileio_errno;
1638 * Some fileio results do not match up with what the semihosting
1639 * operation expects; for these operations, we munge the results
1642 switch (semihosting->op) {
1643 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1645 semihosting->result = fileio_info->param_3;
1647 semihosting->result = 0;
1650 case SEMIHOSTING_SYS_READ: /* 0x06 */
1651 if (result == (int)fileio_info->param_3)
1652 semihosting->result = 0;
1654 semihosting->result = fileio_info->param_3;
1657 case SEMIHOSTING_SYS_SEEK: /* 0x0a */
1659 semihosting->result = 0;
1663 return semihosting->post_result(target);
1666 /* -------------------------------------------------------------------------
1667 * Utility functions. */
1670 * Read all fields of a command from target to buffer.
1672 int semihosting_read_fields(struct target *target, size_t number,
1675 struct semihosting *semihosting = target->semihosting;
1676 /* Use 4-byte multiples to trigger fast memory access. */
1677 return target_read_memory(target, semihosting->param, 4,
1678 number * (semihosting->word_size_bytes / 4), fields);
1682 * Write all fields of a command from buffer to target.
1684 int semihosting_write_fields(struct target *target, size_t number,
1687 struct semihosting *semihosting = target->semihosting;
1688 /* Use 4-byte multiples to trigger fast memory access. */
1689 return target_write_memory(target, semihosting->param, 4,
1690 number * (semihosting->word_size_bytes / 4), fields);
1694 * Extract a field from the buffer, considering register size and endianness.
1696 uint64_t semihosting_get_field(struct target *target, size_t index,
1699 struct semihosting *semihosting = target->semihosting;
1700 if (semihosting->word_size_bytes == 8)
1701 return target_buffer_get_u64(target, fields + (index * 8));
1703 return target_buffer_get_u32(target, fields + (index * 4));
1707 * Store a field in the buffer, considering register size and endianness.
1709 void semihosting_set_field(struct target *target, uint64_t value,
1713 struct semihosting *semihosting = target->semihosting;
1714 if (semihosting->word_size_bytes == 8)
1715 target_buffer_set_u64(target, fields + (index * 8), value);
1717 target_buffer_set_u32(target, fields + (index * 4), value);
1720 /* -------------------------------------------------------------------------
1721 * Semihosting redirect over TCP structs and functions */
1723 static int semihosting_service_new_connection_handler(struct connection *connection)
1725 struct semihosting_tcp_service *service = connection->service->priv;
1726 service->semihosting->tcp_connection = connection;
1731 static int semihosting_service_input_handler(struct connection *connection)
1733 struct semihosting_tcp_service *service = connection->service->priv;
1735 if (!connection->input_pending) {
1736 /* consume received data, not for semihosting IO */
1737 const int buf_len = 100;
1739 int bytes_read = connection_read(connection, buf, buf_len);
1741 if (bytes_read == 0) {
1742 return ERROR_SERVER_REMOTE_CLOSED;
1743 } else if (bytes_read == -1) {
1744 LOG_ERROR("error during read: %s", strerror(errno));
1745 return ERROR_SERVER_REMOTE_CLOSED;
1747 } else if (service->error != ERROR_OK) {
1748 return ERROR_SERVER_REMOTE_CLOSED;
1754 static int semihosting_service_connection_closed_handler(struct connection *connection)
1756 struct semihosting_tcp_service *service = connection->service->priv;
1758 free(service->name);
1765 static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
1767 if (!semihosting->tcp_connection)
1770 struct service *service = semihosting->tcp_connection->service;
1771 remove_service(service->name, service->port);
1772 semihosting->tcp_connection = NULL;
1776 static const struct service_driver semihosting_service_driver = {
1777 .name = "semihosting",
1778 .new_connection_during_keep_alive_handler = NULL,
1779 .new_connection_handler = semihosting_service_new_connection_handler,
1780 .input_handler = semihosting_service_input_handler,
1781 .connection_closed_handler = semihosting_service_connection_closed_handler,
1782 .keep_client_alive_handler = NULL,
1785 /* -------------------------------------------------------------------------
1786 * Common semihosting commands handlers. */
1788 COMMAND_HANDLER(handle_common_semihosting_command)
1790 struct target *target = get_current_target(CMD_CTX);
1793 LOG_ERROR("No target selected");
1797 struct semihosting *semihosting = target->semihosting;
1799 command_print(CMD, "semihosting not supported for current target");
1806 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1808 if (!target_was_examined(target)) {
1809 LOG_ERROR("Target not examined yet");
1813 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1814 LOG_ERROR("Failed to Configure semihosting");
1818 /* FIXME never let that "catch" be dropped! (???) */
1819 semihosting->is_active = is_active;
1822 command_print(CMD, "semihosting is %s",
1823 semihosting->is_active
1824 ? "enabled" : "disabled");
1829 COMMAND_HANDLER(handle_common_semihosting_redirect_command)
1831 struct target *target = get_current_target(CMD_CTX);
1833 if (target == NULL) {
1834 LOG_ERROR("No target selected");
1838 struct semihosting *semihosting = target->semihosting;
1840 command_print(CMD, "semihosting not supported for current target");
1844 if (!semihosting->is_active) {
1845 command_print(CMD, "semihosting not yet enabled for current target");
1849 enum semihosting_redirect_config cfg;
1853 return ERROR_COMMAND_SYNTAX_ERROR;
1855 if (strcmp(CMD_ARGV[0], "disable") == 0) {
1856 cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1858 return ERROR_COMMAND_SYNTAX_ERROR;
1859 } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
1860 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1861 return ERROR_COMMAND_SYNTAX_ERROR;
1865 cfg = SEMIHOSTING_REDIRECT_CFG_ALL;
1866 if (CMD_ARGC == 3) {
1867 if (strcmp(CMD_ARGV[2], "debug") == 0)
1868 cfg = SEMIHOSTING_REDIRECT_CFG_DEBUG;
1869 else if (strcmp(CMD_ARGV[2], "stdio") == 0)
1870 cfg = SEMIHOSTING_REDIRECT_CFG_STDIO;
1871 else if (strcmp(CMD_ARGV[2], "all") != 0)
1872 return ERROR_COMMAND_SYNTAX_ERROR;
1875 return ERROR_COMMAND_SYNTAX_ERROR;
1878 semihosting_tcp_close_cnx(semihosting);
1879 semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1881 if (cfg != SEMIHOSTING_REDIRECT_CFG_NONE) {
1882 struct semihosting_tcp_service *service =
1883 calloc(1, sizeof(struct semihosting_tcp_service));
1885 LOG_ERROR("Failed to allocate semihosting TCP service.");
1889 service->semihosting = semihosting;
1891 service->name = alloc_printf("%s semihosting service", target_name(target));
1892 if (!service->name) {
1893 LOG_ERROR("Out of memory");
1898 int ret = add_service(&semihosting_service_driver,
1901 if (ret != ERROR_OK) {
1902 LOG_ERROR("failed to initialize %s", service->name);
1903 free(service->name);
1909 semihosting->redirect_cfg = cfg;
1914 COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1916 struct target *target = get_current_target(CMD_CTX);
1919 LOG_ERROR("No target selected");
1923 struct semihosting *semihosting = target->semihosting;
1925 command_print(CMD, "semihosting not supported for current target");
1929 if (!semihosting->is_active) {
1930 command_print(CMD, "semihosting not yet enabled for current target");
1935 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1937 command_print(CMD, "semihosting fileio is %s",
1938 semihosting->is_fileio
1939 ? "enabled" : "disabled");
1944 COMMAND_HANDLER(handle_common_semihosting_cmdline)
1946 struct target *target = get_current_target(CMD_CTX);
1950 LOG_ERROR("No target selected");
1954 struct semihosting *semihosting = target->semihosting;
1956 command_print(CMD, "semihosting not supported for current target");
1960 free(semihosting->cmdline);
1961 semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1963 for (i = 1; i < CMD_ARGC; i++) {
1964 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1967 free(semihosting->cmdline);
1968 semihosting->cmdline = cmdline;
1971 command_print(CMD, "semihosting command line is [%s]",
1972 semihosting->cmdline);
1977 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1979 struct target *target = get_current_target(CMD_CTX);
1982 LOG_ERROR("No target selected");
1986 struct semihosting *semihosting = target->semihosting;
1988 command_print(CMD, "semihosting not supported for current target");
1992 if (!semihosting->is_active) {
1993 command_print(CMD, "semihosting not yet enabled for current target");
1998 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
2000 command_print(CMD, "semihosting resumable exit is %s",
2001 semihosting->has_resumable_exit
2002 ? "enabled" : "disabled");
2007 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
2009 struct target *target = get_current_target(CMD_CTX);
2010 struct semihosting *semihosting = target->semihosting;
2013 return ERROR_COMMAND_SYNTAX_ERROR;
2015 if (!semihosting->is_active) {
2016 LOG_ERROR("semihosting not yet enabled for current target");
2020 if (!semihosting_user_op_params) {
2021 LOG_ERROR("This command is usable only from a registered user "
2022 "semihosting event callback.");
2026 command_print_sameline(CMD, "%s", semihosting_user_op_params);
2031 COMMAND_HANDLER(handle_common_semihosting_basedir_command)
2033 struct target *target = get_current_target(CMD_CTX);
2036 return ERROR_COMMAND_SYNTAX_ERROR;
2039 LOG_ERROR("No target selected");
2043 struct semihosting *semihosting = target->semihosting;
2045 command_print(CMD, "semihosting not supported for current target");
2049 if (!semihosting->is_active) {
2050 command_print(CMD, "semihosting not yet enabled for current target");
2055 free(semihosting->basedir);
2056 semihosting->basedir = strdup(CMD_ARGV[0]);
2057 if (!semihosting->basedir) {
2058 command_print(CMD, "semihosting failed to allocate memory for basedir!");
2063 command_print(CMD, "semihosting base dir: %s",
2064 semihosting->basedir ? semihosting->basedir : "");
2069 const struct command_registration semihosting_common_handlers[] = {
2071 .name = "semihosting",
2072 .handler = handle_common_semihosting_command,
2073 .mode = COMMAND_EXEC,
2074 .usage = "['enable'|'disable']",
2075 .help = "activate support for semihosting operations",
2078 .name = "semihosting_redirect",
2079 .handler = handle_common_semihosting_redirect_command,
2080 .mode = COMMAND_EXEC,
2081 .usage = "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2082 .help = "redirect semihosting IO",
2085 .name = "semihosting_cmdline",
2086 .handler = handle_common_semihosting_cmdline,
2087 .mode = COMMAND_EXEC,
2088 .usage = "arguments",
2089 .help = "command line arguments to be passed to program",
2092 .name = "semihosting_fileio",
2093 .handler = handle_common_semihosting_fileio_command,
2094 .mode = COMMAND_EXEC,
2095 .usage = "['enable'|'disable']",
2096 .help = "activate support for semihosting fileio operations",
2099 .name = "semihosting_resexit",
2100 .handler = handle_common_semihosting_resumable_exit_command,
2101 .mode = COMMAND_EXEC,
2102 .usage = "['enable'|'disable']",
2103 .help = "activate support for semihosting resumable exit",
2106 .name = "semihosting_read_user_param",
2107 .handler = handle_common_semihosting_read_user_param_command,
2108 .mode = COMMAND_EXEC,
2110 .help = "read parameters in semihosting-user-cmd-0x10X callbacks",
2113 .name = "semihosting_basedir",
2114 .handler = handle_common_semihosting_basedir_command,
2115 .mode = COMMAND_EXEC,
2117 .help = "set the base directory for semihosting I/O operations",
2119 COMMAND_REGISTRATION_DONE