1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2018 by Liviu Ionescu *
7 * Copyright (C) 2018 by Marvell Technology Group Ltd. *
8 * Written by Nicolas Pitre <nico@marvell.com> *
10 * Copyright (C) 2010 by Spencer Oliver *
11 * spen@spen-soft.co.uk *
13 * Copyright (C) 2016 by Square, Inc. *
14 * Steven Stallion <stallion@squareup.com> *
15 ***************************************************************************/
19 * Common ARM semihosting support.
21 * Semihosting enables code running on a target to use some of the I/O
22 * facilities on the host computer. The target application must be linked
23 * against a library that forwards operation requests by using an
24 * instruction trapped by the debugger.
26 * Details can be found in
27 * "Semihosting for AArch32 and AArch64, Release 2.0"
28 * https://static.docs.arm.com/100863/0200/semihosting.pdf
37 #include "target_type.h"
38 #include "semihosting_common.h"
40 #include <helper/binarybuffer.h>
41 #include <helper/log.h>
45 * It is not possible to use O_... flags defined in sys/stat.h because they
46 * are not guaranteed to match the values defined by the GDB Remote Protocol.
47 * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
50 TARGET_O_RDONLY = 0x000,
51 TARGET_O_WRONLY = 0x001,
52 TARGET_O_RDWR = 0x002,
53 TARGET_O_APPEND = 0x008,
54 TARGET_O_CREAT = 0x200,
55 TARGET_O_TRUNC = 0x400,
56 /* O_EXCL=0x800 is not required in this implementation. */
59 /* GDB remote protocol does not differentiate between text and binary open modes. */
60 static const int open_gdb_modeflags[12] = {
65 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
66 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
67 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC,
68 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_TRUNC,
69 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
70 TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
71 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND,
72 TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND
75 static const int open_host_modeflags[12] = {
80 O_WRONLY | O_CREAT | O_TRUNC,
81 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
82 O_RDWR | O_CREAT | O_TRUNC,
83 O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
84 O_WRONLY | O_CREAT | O_APPEND,
85 O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
86 O_RDWR | O_CREAT | O_APPEND,
87 O_RDWR | O_CREAT | O_APPEND | O_BINARY
90 static int semihosting_common_fileio_info(struct target *target,
91 struct gdb_fileio_info *fileio_info);
92 static int semihosting_common_fileio_end(struct target *target, int result,
93 int fileio_errno, bool ctrl_c);
95 /* Attempts to include gdb_server.h failed. */
96 extern int gdb_actual_connections;
99 * Initialize common semihosting support.
101 * @param target Pointer to the target to initialize.
104 * @return An error status if there is a problem during initialization.
106 int semihosting_common_init(struct target *target, void *setup,
111 target->fileio_info = malloc(sizeof(*target->fileio_info));
112 if (!target->fileio_info) {
113 LOG_ERROR("out of memory");
116 memset(target->fileio_info, 0, sizeof(*target->fileio_info));
118 struct semihosting *semihosting;
119 semihosting = malloc(sizeof(*target->semihosting));
121 LOG_ERROR("out of memory");
125 semihosting->is_active = false;
126 semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
127 semihosting->tcp_connection = NULL;
128 semihosting->stdin_fd = -1;
129 semihosting->stdout_fd = -1;
130 semihosting->stderr_fd = -1;
131 semihosting->is_fileio = false;
132 semihosting->hit_fileio = false;
133 semihosting->is_resumable = false;
134 semihosting->has_resumable_exit = false;
135 semihosting->word_size_bytes = 0;
136 semihosting->op = -1;
137 semihosting->param = 0;
138 semihosting->result = -1;
139 semihosting->sys_errno = -1;
140 semihosting->cmdline = NULL;
141 semihosting->basedir = NULL;
143 /* If possible, update it in setup(). */
144 semihosting->setup_time = clock();
146 semihosting->setup = setup;
147 semihosting->post_result = post_result;
148 semihosting->user_command_extension = NULL;
150 target->semihosting = semihosting;
152 target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
153 target->type->gdb_fileio_end = semihosting_common_fileio_end;
158 struct semihosting_tcp_service {
159 struct semihosting *semihosting;
164 static bool semihosting_is_redirected(struct semihosting *semihosting, int fd)
166 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_NONE)
169 bool is_read_op = false;
171 switch (semihosting->op) {
172 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
173 case SEMIHOSTING_SYS_READC:
176 case SEMIHOSTING_SYS_WRITEC:
177 case SEMIHOSTING_SYS_WRITE0:
178 /* debug operations are redirected when CFG is either DEBUG or ALL */
179 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_STDIO)
183 /* check stdio semihosting operations: READ and WRITE */
184 case SEMIHOSTING_SYS_READ:
187 case SEMIHOSTING_SYS_WRITE:
188 /* stdio operations are redirected when CFG is either STDIO or ALL */
189 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_DEBUG)
198 return fd == semihosting->stdin_fd;
200 /* write operation */
201 return fd == semihosting->stdout_fd || fd == semihosting->stderr_fd;
204 static ssize_t semihosting_redirect_write(struct semihosting *semihosting, void *buf, int size)
206 if (!semihosting->tcp_connection) {
207 LOG_ERROR("No connected TCP client for semihosting");
208 semihosting->sys_errno = EBADF; /* Bad file number */
212 struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
214 int retval = connection_write(semihosting->tcp_connection, buf, size);
217 log_socket_error(service->name);
222 static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void *buf, int size)
224 if (semihosting_is_redirected(semihosting, fd))
225 return semihosting_redirect_write(semihosting, buf, size);
228 return write(fd, buf, size);
231 static ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size)
233 if (!semihosting->tcp_connection) {
234 LOG_ERROR("No connected TCP client for semihosting");
235 semihosting->sys_errno = EBADF; /* Bad file number */
239 struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
241 service->error = ERROR_OK;
242 semihosting->tcp_connection->input_pending = true;
244 int retval = connection_read(semihosting->tcp_connection, buf, size);
247 service->error = ERROR_SERVER_REMOTE_CLOSED;
250 log_socket_error(service->name);
252 semihosting->tcp_connection->input_pending = false;
257 static inline int semihosting_putchar(struct semihosting *semihosting, int fd, int c)
259 if (semihosting_is_redirected(semihosting, fd))
260 return semihosting_redirect_write(semihosting, &c, 1);
262 /* default putchar */
266 static inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, void *buf, int size)
268 if (semihosting_is_redirected(semihosting, fd))
269 return semihosting_redirect_read(semihosting, buf, size);
272 ssize_t result = read(fd, buf, size);
273 semihosting->sys_errno = errno;
278 static inline int semihosting_getchar(struct semihosting *semihosting, int fd)
280 if (semihosting_is_redirected(semihosting, fd)) {
283 if (semihosting_redirect_read(semihosting, &c, 1) > 0)
289 /* default getchar */
294 * User operation parameter string storage buffer. Contains valid data when the
295 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
297 static char *semihosting_user_op_params;
300 * Portable implementation of ARM semihosting calls.
301 * Performs the currently pending semihosting operation
302 * encoded in target->semihosting.
304 int semihosting_common(struct target *target)
306 struct semihosting *semihosting = target->semihosting;
308 /* Silently ignore if the semihosting field was not set. */
312 struct gdb_fileio_info *fileio_info = target->fileio_info;
315 * By default return an error.
316 * The actual result must be set by each function
318 semihosting->result = -1;
320 /* Most operations are resumable, except the two exit calls. */
321 semihosting->is_resumable = true;
325 /* Enough space to hold 4 long words. */
328 LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op,
331 switch (semihosting->op) {
333 case SEMIHOSTING_SYS_CLOCK: /* 0x10 */
335 * Returns the number of centiseconds (hundredths of a second)
336 * since the execution started.
338 * Values returned can be of limited use for some benchmarking
339 * purposes because of communication overhead or other
340 * agent-specific factors. For example, with a debug hardware
341 * unit the request is passed back to the host for execution.
342 * This can lead to unpredictable delays in transmission and
343 * process scheduling.
345 * Use this function to calculate time intervals, by calculating
346 * differences between intervals with and without the code
347 * sequence to be timed.
350 * The PARAMETER REGISTER must contain 0. There are no other
354 * On exit, the RETURN REGISTER contains:
355 * - The number of centiseconds since some arbitrary start
356 * point, if the call is successful.
357 * - –1 if the call is not successful. For example, because
358 * of a communications error.
361 clock_t delta = clock() - semihosting->setup_time;
363 semihosting->result = delta / (CLOCKS_PER_SEC / 100);
367 case SEMIHOSTING_SYS_CLOSE: /* 0x02 */
369 * Closes a file on the host system. The handle must reference
370 * a file that was opened with SYS_OPEN.
373 * On entry, the PARAMETER REGISTER contains a pointer to a
374 * one-field argument block:
375 * - field 1 Contains a handle for an open file.
378 * On exit, the RETURN REGISTER contains:
379 * - 0 if the call is successful
380 * - –1 if the call is not successful.
382 retval = semihosting_read_fields(target, 1, fields);
383 if (retval != ERROR_OK)
386 int fd = semihosting_get_field(target, 0, fields);
387 /* Do not allow to close OpenOCD's own standard streams */
388 if (fd == 0 || fd == 1 || fd == 2) {
389 LOG_DEBUG("ignoring semihosting attempt to close %s",
390 (fd == 0) ? "stdin" :
391 (fd == 1) ? "stdout" : "stderr");
392 /* Just pretend success */
393 if (semihosting->is_fileio) {
394 semihosting->result = 0;
396 semihosting->result = 0;
397 semihosting->sys_errno = 0;
401 /* Close the descriptor */
402 if (semihosting->is_fileio) {
403 semihosting->hit_fileio = true;
404 fileio_info->identifier = "close";
405 fileio_info->param_1 = fd;
407 semihosting->result = close(fd);
408 semihosting->sys_errno = errno;
409 LOG_DEBUG("close(%d)=%" PRId64, fd, semihosting->result);
414 case SEMIHOSTING_SYS_ERRNO: /* 0x13 */
416 * Returns the value of the C library errno variable that is
417 * associated with the semihosting implementation. The errno
418 * variable can be set by a number of C library semihosted
419 * functions, including:
427 * Whether errno is set or not, and to what value, is entirely
428 * host-specific, except where the ISO C standard defines the
432 * There are no parameters. The PARAMETER REGISTER must be 0.
435 * On exit, the RETURN REGISTER contains the value of the C
436 * library errno variable.
438 semihosting->result = semihosting->sys_errno;
441 case SEMIHOSTING_SYS_EXIT: /* 0x18 */
443 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
444 * previous versions of the documentation.
446 * An application calls this operation to report an exception
447 * to the debugger directly. The most common use is to report
448 * that execution has completed, using ADP_Stopped_ApplicationExit.
450 * Note: This semihosting operation provides no means for 32-bit
451 * callers to indicate an application exit with a specified exit
452 * code. Semihosting callers may prefer to check for the presence
453 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
454 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
458 * On entry, the PARAMETER register is set to a reason code
459 * describing the cause of the trap. Not all semihosting client
460 * implementations will necessarily trap every corresponding
461 * event. Important reason codes are:
463 * - ADP_Stopped_ApplicationExit 0x20026
464 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
467 * On entry, the PARAMETER REGISTER contains a pointer to a
468 * two-field argument block:
469 * - field 1 The exception type, which is one of the set of
470 * reason codes in the above tables.
471 * - field 2 A subcode, whose meaning depends on the reason
473 * In particular, if field 1 is ADP_Stopped_ApplicationExit
474 * then field 2 is an exit status code, as passed to the C
475 * standard library exit() function. A simulator receiving
476 * this request must notify a connected debugger, if present,
477 * and then exit with the specified status.
480 * No return is expected from these calls. However, it is
481 * possible for the debugger to request that the application
482 * continues by performing an RDI_Execute request or equivalent.
483 * In this case, execution continues with the registers as they
484 * were on entry to the operation, or as subsequently modified
487 if (semihosting->word_size_bytes == 8) {
488 retval = semihosting_read_fields(target, 2, fields);
489 if (retval != ERROR_OK)
492 int type = semihosting_get_field(target, 0, fields);
493 int code = semihosting_get_field(target, 1, fields);
495 if (type == ADP_STOPPED_APPLICATION_EXIT) {
496 if (!gdb_actual_connections)
500 "semihosting: *** application exited with %d ***\n",
505 "semihosting: application exception %#x\n",
510 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
511 if (!gdb_actual_connections)
515 "semihosting: *** application exited normally ***\n");
517 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
518 /* Chosen more or less arbitrarily to have a nicer message,
519 * otherwise all other return the same exit code 1. */
520 if (!gdb_actual_connections)
524 "semihosting: *** application exited with error ***\n");
527 if (!gdb_actual_connections)
531 "semihosting: application exception %#x\n",
532 (unsigned) semihosting->param);
536 if (!semihosting->has_resumable_exit) {
537 semihosting->is_resumable = false;
538 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
542 case SEMIHOSTING_SYS_EXIT_EXTENDED: /* 0x20 */
544 * This operation is only supported if the semihosting extension
545 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
546 * reported using feature byte 0, bit 0. If this extension is
547 * supported, then the implementation provides a means to
548 * report a normal exit with a nonzero exit status in both 32-bit
549 * and 64-bit semihosting APIs.
551 * The implementation must provide the semihosting call
552 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
554 * SYS_EXIT_EXTENDED is used by an application to report an
555 * exception or exit to the debugger directly. The most common
556 * use is to report that execution has completed, using
557 * ADP_Stopped_ApplicationExit.
560 * On entry, the PARAMETER REGISTER contains a pointer to a
561 * two-field argument block:
562 * - field 1 The exception type, which should be one of the set
563 * of reason codes that are documented for the SYS_EXIT
564 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
565 * - field 2 A subcode, whose meaning depends on the reason
566 * code in field 1. In particular, if field 1 is
567 * ADP_Stopped_ApplicationExit then field 2 is an exit status
568 * code, as passed to the C standard library exit() function.
569 * A simulator receiving this request must notify a connected
570 * debugger, if present, and then exit with the specified status.
573 * No return is expected from these calls.
575 * For the A64 API, this call is identical to the behavior of
576 * the mandatory SYS_EXIT (0x18) call. If this extension is
577 * supported, then both calls must be implemented.
579 retval = semihosting_read_fields(target, 2, fields);
580 if (retval != ERROR_OK)
583 int type = semihosting_get_field(target, 0, fields);
584 int code = semihosting_get_field(target, 1, fields);
586 if (type == ADP_STOPPED_APPLICATION_EXIT) {
587 if (!gdb_actual_connections)
591 "semihosting: *** application exited with %d ***\n",
595 fprintf(stderr, "semihosting: exception %#x\n",
599 if (!semihosting->has_resumable_exit) {
600 semihosting->is_resumable = false;
601 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
605 case SEMIHOSTING_SYS_FLEN: /* 0x0C */
607 * Returns the length of a specified file.
610 * On entry, the PARAMETER REGISTER contains a pointer to a
611 * one-field argument block:
612 * - field 1 A handle for a previously opened, seekable file
616 * On exit, the RETURN REGISTER contains:
617 * - The current length of the file object, if the call is
619 * - –1 if an error occurs.
621 if (semihosting->is_fileio) {
622 semihosting->result = -1;
623 semihosting->sys_errno = EINVAL;
625 retval = semihosting_read_fields(target, 1, fields);
626 if (retval != ERROR_OK)
629 int fd = semihosting_get_field(target, 0, fields);
631 semihosting->result = fstat(fd, &buf);
632 if (semihosting->result == -1) {
633 semihosting->sys_errno = errno;
634 LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result);
637 LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result);
638 semihosting->result = buf.st_size;
642 case SEMIHOSTING_SYS_GET_CMDLINE: /* 0x15 */
644 * Returns the command line that is used for the call to the
645 * executable, that is, argc and argv.
648 * On entry, the PARAMETER REGISTER points to a two-field data
649 * block to be used for returning the command string and its length:
650 * - field 1 A pointer to a buffer of at least the size that is
651 * specified in field 2.
652 * - field 2 The length of the buffer in bytes.
656 * If the call is successful, then the RETURN REGISTER contains 0,
657 * the PARAMETER REGISTER is unchanged, and the data block is
658 * updated as follows:
659 * - field 1 A pointer to a null-terminated string of the command
661 * - field 2 The length of the string in bytes.
662 * If the call is not successful, then the RETURN REGISTER
665 * Note: The semihosting implementation might impose limits on
666 * the maximum length of the string that can be transferred.
667 * However, the implementation must be able to support a
668 * command-line length of at least 80 bytes.
670 retval = semihosting_read_fields(target, 2, fields);
671 if (retval != ERROR_OK)
674 uint64_t addr = semihosting_get_field(target, 0, fields);
675 size_t size = semihosting_get_field(target, 1, fields);
677 char *arg = semihosting->cmdline ?
678 semihosting->cmdline : "";
679 uint32_t len = strlen(arg) + 1;
681 semihosting->result = -1;
683 semihosting_set_field(target, len, 1, fields);
684 retval = target_write_buffer(target, addr, len,
686 if (retval != ERROR_OK)
688 semihosting->result = 0;
690 retval = semihosting_write_fields(target, 2, fields);
691 if (retval != ERROR_OK)
694 LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64, arg, semihosting->result);
698 case SEMIHOSTING_SYS_HEAPINFO: /* 0x16 */
700 * Returns the system stack and heap parameters.
703 * On entry, the PARAMETER REGISTER contains the address of a
704 * pointer to a four-field data block. The contents of the data
705 * block are filled by the function. The following C-like
706 * pseudocode describes the layout of the block:
715 * On exit, the PARAMETER REGISTER is unchanged and the data
716 * block has been updated.
718 retval = semihosting_read_fields(target, 1, fields);
719 if (retval != ERROR_OK)
722 uint64_t addr = semihosting_get_field(target, 0, fields);
723 /* tell the remote we have no idea */
724 memset(fields, 0, 4 * semihosting->word_size_bytes);
725 retval = target_write_memory(target, addr, 4,
726 semihosting->word_size_bytes,
728 if (retval != ERROR_OK)
730 semihosting->result = 0;
734 case SEMIHOSTING_SYS_ISERROR: /* 0x08 */
736 * Determines whether the return code from another semihosting
737 * call is an error status or not.
739 * This call is passed a parameter block containing the error
743 * On entry, the PARAMETER REGISTER contains a pointer to a
744 * one-field data block:
745 * - field 1 The required status word to check.
748 * On exit, the RETURN REGISTER contains:
749 * - 0 if the status field is not an error indication
750 * - A nonzero value if the status field is an error indication.
752 retval = semihosting_read_fields(target, 1, fields);
753 if (retval != ERROR_OK)
756 uint64_t code = semihosting_get_field(target, 0, fields);
757 semihosting->result = (code != 0);
760 case SEMIHOSTING_SYS_ISTTY: /* 0x09 */
762 * Checks whether a file is connected to an interactive device.
765 * On entry, the PARAMETER REGISTER contains a pointer to a
766 * one-field argument block:
767 * field 1 A handle for a previously opened file object.
770 * On exit, the RETURN REGISTER contains:
771 * - 1 if the handle identifies an interactive device.
772 * - 0 if the handle identifies a file.
773 * - A value other than 1 or 0 if an error occurs.
775 if (semihosting->is_fileio) {
776 semihosting->hit_fileio = true;
777 fileio_info->identifier = "isatty";
778 fileio_info->param_1 = semihosting->param;
780 retval = semihosting_read_fields(target, 1, fields);
781 if (retval != ERROR_OK)
783 int fd = semihosting_get_field(target, 0, fields);
784 semihosting->result = isatty(fd);
785 semihosting->sys_errno = errno;
786 LOG_DEBUG("isatty(%d)=%" PRId64, fd, semihosting->result);
790 case SEMIHOSTING_SYS_OPEN: /* 0x01 */
792 * Opens a file on the host system.
794 * The file path is specified either as relative to the current
795 * directory of the host process, or absolute, using the path
796 * conventions of the host operating system.
798 * Semihosting implementations must support opening the special
799 * path name :semihosting-features as part of the semihosting
800 * extensions reporting mechanism.
802 * ARM targets interpret the special path name :tt as meaning
803 * the console input stream, for an open-read or the console
804 * output stream, for an open-write. Opening these streams is
805 * performed as part of the standard startup code for those
806 * applications that reference the C stdio streams. The
807 * semihosting extension SH_EXT_STDOUT_STDERR allows the
808 * semihosting caller to open separate output streams
809 * corresponding to stdout and stderr. This extension is
810 * reported using feature byte 0, bit 1. Use SYS_OPEN with
811 * the special path name :semihosting-features to access the
814 * If this extension is supported, the implementation must
815 * support the following additional semantics to SYS_OPEN:
816 * - If the special path name :tt is opened with an fopen
817 * mode requesting write access (w, wb, w+, or w+b), then
818 * this is a request to open stdout.
819 * - If the special path name :tt is opened with a mode
820 * requesting append access (a, ab, a+, or a+b), then this is
821 * a request to open stderr.
824 * On entry, the PARAMETER REGISTER contains a pointer to a
825 * three-field argument block:
826 * - field 1 A pointer to a null-terminated string containing
827 * a file or device name.
828 * - field 2 An integer that specifies the file opening mode.
829 * - field 3 An integer that gives the length of the string
830 * pointed to by field 1.
832 * The length does not include the terminating null character
833 * that must be present.
836 * On exit, the RETURN REGISTER contains:
837 * - A nonzero handle if the call is successful.
838 * - –1 if the call is not successful.
840 retval = semihosting_read_fields(target, 3, fields);
841 if (retval != ERROR_OK)
844 uint64_t addr = semihosting_get_field(target, 0, fields);
845 uint32_t mode = semihosting_get_field(target, 1, fields);
846 size_t len = semihosting_get_field(target, 2, fields);
849 semihosting->result = -1;
850 semihosting->sys_errno = EINVAL;
853 size_t basedir_len = semihosting->basedir ? strlen(semihosting->basedir) : 0;
854 uint8_t *fn = malloc(basedir_len + len + 2);
856 semihosting->result = -1;
857 semihosting->sys_errno = ENOMEM;
859 if (basedir_len > 0) {
860 strcpy((char *)fn, semihosting->basedir);
861 if (fn[basedir_len - 1] != '/')
862 fn[basedir_len++] = '/';
864 retval = target_read_memory(target, addr, 1, len, fn + basedir_len);
865 if (retval != ERROR_OK) {
869 fn[basedir_len + len] = 0;
870 /* TODO: implement the :semihosting-features special file.
872 if (semihosting->is_fileio) {
873 if (strcmp((char *)fn, ":semihosting-features") == 0) {
874 semihosting->result = -1;
875 semihosting->sys_errno = EINVAL;
876 } else if (strcmp((char *)fn, ":tt") == 0) {
878 semihosting->result = 0;
880 semihosting->result = 1;
882 semihosting->result = 2;
884 semihosting->result = -1;
886 semihosting->hit_fileio = true;
887 fileio_info->identifier = "open";
888 fileio_info->param_1 = addr;
889 fileio_info->param_2 = len;
890 fileio_info->param_3 = open_gdb_modeflags[mode];
891 fileio_info->param_4 = 0644;
894 if (strcmp((char *)fn, ":tt") == 0) {
896 * - 0-3 ("r") for stdin,
897 * - 4-7 ("w") for stdout,
898 * - 8-11 ("a") for stderr */
900 int fd = dup(STDIN_FILENO);
901 semihosting->result = fd;
902 semihosting->stdin_fd = fd;
903 semihosting->sys_errno = errno;
904 LOG_DEBUG("dup(STDIN)=%" PRId64, semihosting->result);
905 } else if (mode < 8) {
906 int fd = dup(STDOUT_FILENO);
907 semihosting->result = fd;
908 semihosting->stdout_fd = fd;
909 semihosting->sys_errno = errno;
910 LOG_DEBUG("dup(STDOUT)=%" PRId64, semihosting->result);
912 int fd = dup(STDERR_FILENO);
913 semihosting->result = fd;
914 semihosting->stderr_fd = fd;
915 semihosting->sys_errno = errno;
916 LOG_DEBUG("dup(STDERR)=%" PRId64, semihosting->result);
919 /* cygwin requires the permission setting
920 * otherwise it will fail to reopen a previously
922 semihosting->result = open((char *)fn,
923 open_host_modeflags[mode],
925 semihosting->sys_errno = errno;
926 LOG_DEBUG("open('%s')=%" PRId64, fn, semihosting->result);
934 case SEMIHOSTING_SYS_READ: /* 0x06 */
936 * Reads the contents of a file into a buffer. The file position
937 * is specified either:
938 * - Explicitly by a SYS_SEEK.
939 * - Implicitly one byte beyond the previous SYS_READ or
942 * The file position is at the start of the file when it is
943 * opened, and is lost when the file is closed. Perform the
944 * file operation as a single action whenever possible. For
945 * example, do not split a read of 16KB into four 4KB chunks
946 * unless there is no alternative.
949 * On entry, the PARAMETER REGISTER contains a pointer to a
950 * three-field data block:
951 * - field 1 Contains a handle for a file previously opened
953 * - field 2 Points to a buffer.
954 * - field 3 Contains the number of bytes to read to the buffer
958 * On exit, the RETURN REGISTER contains the number of bytes not
959 * filled in the buffer (buffer_length - bytes_read) as follows:
960 * - If the RETURN REGISTER is 0, the entire buffer was
961 * successfully filled.
962 * - If the RETURN REGISTER is the same as field 3, no bytes
963 * were read (EOF can be assumed).
964 * - If the RETURN REGISTER contains a value smaller than
965 * field 3, the read succeeded but the buffer was only partly
966 * filled. For interactive devices, this is the most common
969 retval = semihosting_read_fields(target, 3, fields);
970 if (retval != ERROR_OK)
973 int fd = semihosting_get_field(target, 0, fields);
974 uint64_t addr = semihosting_get_field(target, 1, fields);
975 size_t len = semihosting_get_field(target, 2, fields);
976 if (semihosting->is_fileio) {
977 semihosting->hit_fileio = true;
978 fileio_info->identifier = "read";
979 fileio_info->param_1 = fd;
980 fileio_info->param_2 = addr;
981 fileio_info->param_3 = len;
983 uint8_t *buf = malloc(len);
985 semihosting->result = -1;
986 semihosting->sys_errno = ENOMEM;
988 semihosting->result = semihosting_read(semihosting, fd, buf, len);
989 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%" PRId64,
993 semihosting->result);
994 if (semihosting->result >= 0) {
995 retval = target_write_buffer(target, addr,
998 if (retval != ERROR_OK) {
1002 /* the number of bytes NOT filled in */
1003 semihosting->result = len -
1004 semihosting->result;
1012 case SEMIHOSTING_SYS_READC: /* 0x07 */
1014 * Reads a byte from the console.
1017 * The PARAMETER REGISTER must contain 0. There are no other
1018 * parameters or values possible.
1021 * On exit, the RETURN REGISTER contains the byte read from
1024 if (semihosting->is_fileio) {
1025 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1028 semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);
1029 LOG_DEBUG("getchar()=%" PRId64, semihosting->result);
1032 case SEMIHOSTING_SYS_REMOVE: /* 0x0E */
1034 * Deletes a specified file on the host filing system.
1037 * On entry, the PARAMETER REGISTER contains a pointer to a
1038 * two-field argument block:
1039 * - field 1 Points to a null-terminated string that gives the
1040 * path name of the file to be deleted.
1041 * - field 2 The length of the string.
1044 * On exit, the RETURN REGISTER contains:
1045 * - 0 if the delete is successful
1046 * - A nonzero, host-specific error code if the delete fails.
1048 retval = semihosting_read_fields(target, 2, fields);
1049 if (retval != ERROR_OK)
1052 uint64_t addr = semihosting_get_field(target, 0, fields);
1053 size_t len = semihosting_get_field(target, 1, fields);
1054 if (semihosting->is_fileio) {
1055 semihosting->hit_fileio = true;
1056 fileio_info->identifier = "unlink";
1057 fileio_info->param_1 = addr;
1058 fileio_info->param_2 = len;
1060 uint8_t *fn = malloc(len+1);
1062 semihosting->result = -1;
1063 semihosting->sys_errno = ENOMEM;
1066 target_read_memory(target, addr, 1, len,
1068 if (retval != ERROR_OK) {
1073 semihosting->result = remove((char *)fn);
1074 semihosting->sys_errno = errno;
1075 LOG_DEBUG("remove('%s')=%" PRId64, fn, semihosting->result);
1083 case SEMIHOSTING_SYS_RENAME: /* 0x0F */
1085 * Renames a specified file.
1088 * On entry, the PARAMETER REGISTER contains a pointer to a
1089 * four-field data block:
1090 * - field 1 A pointer to the name of the old file.
1091 * - field 2 The length of the old filename.
1092 * - field 3 A pointer to the new filename.
1093 * - field 4 The length of the new filename. Both strings are
1097 * On exit, the RETURN REGISTER contains:
1098 * - 0 if the rename is successful.
1099 * - A nonzero, host-specific error code if the rename fails.
1101 retval = semihosting_read_fields(target, 4, fields);
1102 if (retval != ERROR_OK)
1105 uint64_t addr1 = semihosting_get_field(target, 0, fields);
1106 size_t len1 = semihosting_get_field(target, 1, fields);
1107 uint64_t addr2 = semihosting_get_field(target, 2, fields);
1108 size_t len2 = semihosting_get_field(target, 3, fields);
1109 if (semihosting->is_fileio) {
1110 semihosting->hit_fileio = true;
1111 fileio_info->identifier = "rename";
1112 fileio_info->param_1 = addr1;
1113 fileio_info->param_2 = len1;
1114 fileio_info->param_3 = addr2;
1115 fileio_info->param_4 = len2;
1117 uint8_t *fn1 = malloc(len1+1);
1118 uint8_t *fn2 = malloc(len2+1);
1122 semihosting->result = -1;
1123 semihosting->sys_errno = ENOMEM;
1125 retval = target_read_memory(target, addr1, 1, len1,
1127 if (retval != ERROR_OK) {
1132 retval = target_read_memory(target, addr2, 1, len2,
1134 if (retval != ERROR_OK) {
1141 semihosting->result = rename((char *)fn1,
1143 semihosting->sys_errno = errno;
1144 LOG_DEBUG("rename('%s', '%s')=%" PRId64 " %d", fn1, fn2, semihosting->result, errno);
1152 case SEMIHOSTING_SYS_SEEK: /* 0x0A */
1154 * Seeks to a specified position in a file using an offset
1155 * specified from the start of the file. The file is assumed
1156 * to be a byte array and the offset is given in bytes.
1159 * On entry, the PARAMETER REGISTER contains a pointer to a
1160 * two-field data block:
1161 * - field 1 A handle for a seekable file object.
1162 * - field 2 The absolute byte position to seek to.
1165 * On exit, the RETURN REGISTER contains:
1166 * - 0 if the request is successful.
1167 * - A negative value if the request is not successful.
1168 * Use SYS_ERRNO to read the value of the host errno variable
1169 * describing the error.
1171 * Note: The effect of seeking outside the current extent of
1172 * the file object is undefined.
1174 retval = semihosting_read_fields(target, 2, fields);
1175 if (retval != ERROR_OK)
1178 int fd = semihosting_get_field(target, 0, fields);
1179 off_t pos = semihosting_get_field(target, 1, fields);
1180 if (semihosting->is_fileio) {
1181 semihosting->hit_fileio = true;
1182 fileio_info->identifier = "lseek";
1183 fileio_info->param_1 = fd;
1184 fileio_info->param_2 = pos;
1185 fileio_info->param_3 = SEEK_SET;
1187 semihosting->result = lseek(fd, pos, SEEK_SET);
1188 semihosting->sys_errno = errno;
1189 LOG_DEBUG("lseek(%d, %d)=%" PRId64, fd, (int)pos, semihosting->result);
1190 if (semihosting->result == pos)
1191 semihosting->result = 0;
1196 case SEMIHOSTING_SYS_SYSTEM: /* 0x12 */
1198 * Passes a command to the host command-line interpreter.
1199 * This enables you to execute a system command such as dir,
1200 * ls, or pwd. The terminal I/O is on the host, and is not
1201 * visible to the target.
1204 * On entry, the PARAMETER REGISTER contains a pointer to a
1205 * two-field argument block:
1206 * - field 1 Points to a string to be passed to the host
1207 * command-line interpreter.
1208 * - field 2 The length of the string.
1211 * On exit, the RETURN REGISTER contains the return status.
1214 /* Provide SYS_SYSTEM functionality. Uses the
1215 * libc system command, there may be a reason *NOT*
1216 * to use this, but as I can't think of one, I
1217 * implemented it this way.
1219 retval = semihosting_read_fields(target, 2, fields);
1220 if (retval != ERROR_OK)
1223 uint64_t addr = semihosting_get_field(target, 0, fields);
1224 size_t len = semihosting_get_field(target, 1, fields);
1225 if (semihosting->is_fileio) {
1226 semihosting->hit_fileio = true;
1227 fileio_info->identifier = "system";
1228 fileio_info->param_1 = addr;
1229 fileio_info->param_2 = len;
1231 uint8_t *cmd = malloc(len+1);
1233 semihosting->result = -1;
1234 semihosting->sys_errno = ENOMEM;
1236 retval = target_read_memory(target,
1241 if (retval != ERROR_OK) {
1246 semihosting->result = system(
1248 LOG_DEBUG("system('%s')=%" PRId64, cmd, semihosting->result);
1257 case SEMIHOSTING_SYS_TIME: /* 0x11 */
1259 * Returns the number of seconds since 00:00 January 1, 1970.
1260 * This value is real-world time, regardless of any debug agent
1264 * There are no parameters.
1267 * On exit, the RETURN REGISTER contains the number of seconds.
1269 semihosting->result = time(NULL);
1272 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1274 * Writes the contents of a buffer to a specified file at the
1275 * current file position. The file position is specified either:
1276 * - Explicitly, by a SYS_SEEK.
1277 * - Implicitly as one byte beyond the previous SYS_READ or
1278 * SYS_WRITE request.
1280 * The file position is at the start of the file when the file
1281 * is opened, and is lost when the file is closed.
1283 * Perform the file operation as a single action whenever
1284 * possible. For example, do not split a write of 16KB into
1285 * four 4KB chunks unless there is no alternative.
1288 * On entry, the PARAMETER REGISTER contains a pointer to a
1289 * three-field data block:
1290 * - field 1 Contains a handle for a file previously opened
1292 * - field 2 Points to the memory containing the data to be written.
1293 * - field 3 Contains the number of bytes to be written from
1294 * the buffer to the file.
1297 * On exit, the RETURN REGISTER contains:
1298 * - 0 if the call is successful.
1299 * - The number of bytes that are not written, if there is an error.
1301 retval = semihosting_read_fields(target, 3, fields);
1302 if (retval != ERROR_OK)
1305 int fd = semihosting_get_field(target, 0, fields);
1306 uint64_t addr = semihosting_get_field(target, 1, fields);
1307 size_t len = semihosting_get_field(target, 2, fields);
1308 if (semihosting->is_fileio) {
1309 semihosting->hit_fileio = true;
1310 fileio_info->identifier = "write";
1311 fileio_info->param_1 = fd;
1312 fileio_info->param_2 = addr;
1313 fileio_info->param_3 = len;
1315 uint8_t *buf = malloc(len);
1317 semihosting->result = -1;
1318 semihosting->sys_errno = ENOMEM;
1320 retval = target_read_buffer(target, addr, len, buf);
1321 if (retval != ERROR_OK) {
1325 semihosting->result = semihosting_write(semihosting, fd, buf, len);
1326 semihosting->sys_errno = errno;
1327 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%" PRId64,
1331 semihosting->result);
1332 if (semihosting->result >= 0) {
1333 /* The number of bytes that are NOT written.
1335 semihosting->result = len -
1336 semihosting->result;
1345 case SEMIHOSTING_SYS_WRITEC: /* 0x03 */
1347 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1348 * to the debug channel. When executed under a semihosting
1349 * debugger, the character appears on the host debugger console.
1352 * On entry, the PARAMETER REGISTER contains a pointer to the
1356 * None. The RETURN REGISTER is corrupted.
1358 if (semihosting->is_fileio) {
1359 semihosting->hit_fileio = true;
1360 fileio_info->identifier = "write";
1361 fileio_info->param_1 = 1;
1362 fileio_info->param_2 = semihosting->param;
1363 fileio_info->param_3 = 1;
1365 uint64_t addr = semihosting->param;
1367 retval = target_read_memory(target, addr, 1, 1, &c);
1368 if (retval != ERROR_OK)
1370 semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1371 semihosting->result = 0;
1375 case SEMIHOSTING_SYS_WRITE0: /* 0x04 */
1377 * Writes a null-terminated string to the debug channel.
1378 * When executed under a semihosting debugger, the characters
1379 * appear on the host debugger console.
1382 * On entry, the PARAMETER REGISTER contains a pointer to the
1383 * first byte of the string.
1386 * None. The RETURN REGISTER is corrupted.
1388 if (semihosting->is_fileio) {
1390 uint64_t addr = semihosting->param;
1393 retval = target_read_memory(target, addr, 1, 1, &c);
1394 if (retval != ERROR_OK)
1400 semihosting->hit_fileio = true;
1401 fileio_info->identifier = "write";
1402 fileio_info->param_1 = 1;
1403 fileio_info->param_2 = semihosting->param;
1404 fileio_info->param_3 = count;
1406 uint64_t addr = semihosting->param;
1409 retval = target_read_memory(target, addr++, 1, 1, &c);
1410 if (retval != ERROR_OK)
1414 semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1416 semihosting->result = 0;
1420 case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107:
1422 * This is a user defined operation (while user cmds 0x100-0x1ff
1423 * are possible, only 0x100-0x107 are currently implemented).
1425 * Reads the user operation parameters from target, then fires the
1426 * corresponding target event. When the target callbacks returned,
1427 * cleans up the command parameter buffer.
1430 * On entry, the PARAMETER REGISTER contains a pointer to a
1431 * two-field data block:
1432 * - field 1 Contains a pointer to the bound command parameter
1434 * - field 2 Contains the command parameter string length
1437 * On exit, the RETURN REGISTER contains the return status.
1439 if (semihosting->user_command_extension) {
1440 retval = semihosting->user_command_extension(target);
1441 if (retval != ERROR_NOT_IMPLEMENTED)
1443 /* If custom user command not handled, we are looking for the TCL handler */
1446 assert(!semihosting_user_op_params);
1447 retval = semihosting_read_fields(target, 2, fields);
1448 if (retval != ERROR_OK) {
1449 LOG_ERROR("Failed to read fields for user defined command"
1450 " op=0x%x", semihosting->op);
1454 uint64_t addr = semihosting_get_field(target, 0, fields);
1456 size_t len = semihosting_get_field(target, 1, fields);
1457 if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
1458 LOG_ERROR("The maximum length for user defined command "
1459 "parameter is %u, received length is %zu (op=0x%x)",
1460 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
1466 semihosting_user_op_params = malloc(len + 1);
1467 if (!semihosting_user_op_params)
1469 semihosting_user_op_params[len] = 0;
1471 retval = target_read_buffer(target, addr, len,
1472 (uint8_t *)(semihosting_user_op_params));
1473 if (retval != ERROR_OK) {
1474 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1476 free(semihosting_user_op_params);
1477 semihosting_user_op_params = NULL;
1481 target_handle_event(target, semihosting->op);
1482 free(semihosting_user_op_params);
1483 semihosting_user_op_params = NULL;
1484 semihosting->result = 0;
1487 case SEMIHOSTING_SYS_ELAPSED: /* 0x30 */
1489 * Returns the number of elapsed target ticks since execution
1491 * Use SYS_TICKFREQ to determine the tick frequency.
1494 * On entry, the PARAMETER REGISTER points to a two-field data
1495 * block to be used for returning the number of elapsed ticks:
1496 * - field 1 The least significant field and is at the low address.
1497 * - field 2 The most significant field and is at the high address.
1500 * On entry the PARAMETER REGISTER points to a one-field data
1501 * block to be used for returning the number of elapsed ticks:
1502 * - field 1 The number of elapsed ticks as a 64-bit value.
1506 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1507 * REGISTER is unchanged, and the data block pointed to by the
1508 * PARAMETER REGISTER is filled in with the number of elapsed
1510 * - On failure, the RETURN REGISTER contains -1, and the
1511 * PARAMETER REGISTER contains -1.
1513 * Note: Some semihosting implementations might not support this
1514 * semihosting operation, and they always return -1 in the
1518 case SEMIHOSTING_SYS_TICKFREQ: /* 0x31 */
1520 * Returns the tick frequency.
1523 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1526 * On exit, the RETURN REGISTER contains either:
1527 * - The number of ticks per second.
1528 * - –1 if the target does not know the value of one tick.
1530 * Note: Some semihosting implementations might not support
1531 * this semihosting operation, and they always return -1 in the
1535 case SEMIHOSTING_SYS_TMPNAM: /* 0x0D */
1537 * Returns a temporary name for a file identified by a system
1541 * On entry, the PARAMETER REGISTER contains a pointer to a
1542 * three-word argument block:
1543 * - field 1 A pointer to a buffer.
1544 * - field 2 A target identifier for this filename. Its value
1545 * must be an integer in the range 0-255.
1546 * - field 3 Contains the length of the buffer. The length must
1547 * be at least the value of L_tmpnam on the host system.
1550 * On exit, the RETURN REGISTER contains:
1551 * - 0 if the call is successful.
1552 * - –1 if an error occurs.
1554 * The buffer pointed to by the PARAMETER REGISTER contains
1555 * the filename, prefixed with a suitable directory name.
1556 * If you use the same target identifier again, the same
1557 * filename is returned.
1559 * Note: The returned string must be null-terminated.
1563 fprintf(stderr, "semihosting: unsupported call %#x\n",
1564 (unsigned) semihosting->op);
1565 semihosting->result = -1;
1566 semihosting->sys_errno = ENOTSUP;
1569 if (!semihosting->hit_fileio) {
1570 retval = semihosting->post_result(target);
1571 if (retval != ERROR_OK) {
1572 LOG_ERROR("Failed to post semihosting result");
1580 /* -------------------------------------------------------------------------
1581 * Local functions. */
1583 static int semihosting_common_fileio_info(struct target *target,
1584 struct gdb_fileio_info *fileio_info)
1586 struct semihosting *semihosting = target->semihosting;
1591 * To avoid unnecessary duplication, semihosting prepares the
1592 * fileio_info structure out-of-band when the target halts. See
1593 * do_semihosting for more detail.
1595 if (!semihosting->is_fileio || !semihosting->hit_fileio)
1601 static int semihosting_common_fileio_end(struct target *target, int result,
1602 int fileio_errno, bool ctrl_c)
1604 struct gdb_fileio_info *fileio_info = target->fileio_info;
1605 struct semihosting *semihosting = target->semihosting;
1609 /* clear pending status */
1610 semihosting->hit_fileio = false;
1612 semihosting->result = result;
1613 semihosting->sys_errno = fileio_errno;
1616 * Some fileio results do not match up with what the semihosting
1617 * operation expects; for these operations, we munge the results
1620 switch (semihosting->op) {
1621 case SEMIHOSTING_SYS_WRITE: /* 0x05 */
1622 case SEMIHOSTING_SYS_READ: /* 0x06 */
1624 semihosting->result = fileio_info->param_3; /* Zero bytes read/written. */
1626 semihosting->result = (int64_t)fileio_info->param_3 - result;
1629 case SEMIHOSTING_SYS_SEEK: /* 0x0a */
1631 semihosting->result = 0;
1635 return semihosting->post_result(target);
1638 /* -------------------------------------------------------------------------
1639 * Utility functions. */
1642 * Read all fields of a command from target to buffer.
1644 int semihosting_read_fields(struct target *target, size_t number,
1647 struct semihosting *semihosting = target->semihosting;
1648 /* Use 4-byte multiples to trigger fast memory access. */
1649 return target_read_memory(target, semihosting->param, 4,
1650 number * (semihosting->word_size_bytes / 4), fields);
1654 * Write all fields of a command from buffer to target.
1656 int semihosting_write_fields(struct target *target, size_t number,
1659 struct semihosting *semihosting = target->semihosting;
1660 /* Use 4-byte multiples to trigger fast memory access. */
1661 return target_write_memory(target, semihosting->param, 4,
1662 number * (semihosting->word_size_bytes / 4), fields);
1666 * Extract a field from the buffer, considering register size and endianness.
1668 uint64_t semihosting_get_field(struct target *target, size_t index,
1671 struct semihosting *semihosting = target->semihosting;
1672 if (semihosting->word_size_bytes == 8)
1673 return target_buffer_get_u64(target, fields + (index * 8));
1675 return target_buffer_get_u32(target, fields + (index * 4));
1679 * Store a field in the buffer, considering register size and endianness.
1681 void semihosting_set_field(struct target *target, uint64_t value,
1685 struct semihosting *semihosting = target->semihosting;
1686 if (semihosting->word_size_bytes == 8)
1687 target_buffer_set_u64(target, fields + (index * 8), value);
1689 target_buffer_set_u32(target, fields + (index * 4), value);
1692 /* -------------------------------------------------------------------------
1693 * Semihosting redirect over TCP structs and functions */
1695 static int semihosting_service_new_connection_handler(struct connection *connection)
1697 struct semihosting_tcp_service *service = connection->service->priv;
1698 service->semihosting->tcp_connection = connection;
1703 static int semihosting_service_input_handler(struct connection *connection)
1705 struct semihosting_tcp_service *service = connection->service->priv;
1707 if (!connection->input_pending) {
1708 /* consume received data, not for semihosting IO */
1709 const int buf_len = 100;
1711 int bytes_read = connection_read(connection, buf, buf_len);
1713 if (bytes_read == 0) {
1714 return ERROR_SERVER_REMOTE_CLOSED;
1715 } else if (bytes_read == -1) {
1716 LOG_ERROR("error during read: %s", strerror(errno));
1717 return ERROR_SERVER_REMOTE_CLOSED;
1719 } else if (service->error != ERROR_OK) {
1720 return ERROR_SERVER_REMOTE_CLOSED;
1726 static int semihosting_service_connection_closed_handler(struct connection *connection)
1728 struct semihosting_tcp_service *service = connection->service->priv;
1730 free(service->name);
1737 static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
1739 if (!semihosting->tcp_connection)
1742 struct service *service = semihosting->tcp_connection->service;
1743 remove_service(service->name, service->port);
1744 semihosting->tcp_connection = NULL;
1748 static const struct service_driver semihosting_service_driver = {
1749 .name = "semihosting",
1750 .new_connection_during_keep_alive_handler = NULL,
1751 .new_connection_handler = semihosting_service_new_connection_handler,
1752 .input_handler = semihosting_service_input_handler,
1753 .connection_closed_handler = semihosting_service_connection_closed_handler,
1754 .keep_client_alive_handler = NULL,
1757 /* -------------------------------------------------------------------------
1758 * Common semihosting commands handlers. */
1760 COMMAND_HANDLER(handle_common_semihosting_command)
1762 struct target *target = get_current_target(CMD_CTX);
1765 LOG_ERROR("No target selected");
1769 struct semihosting *semihosting = target->semihosting;
1771 command_print(CMD, "semihosting not supported for current target");
1778 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1780 if (!target_was_examined(target)) {
1781 LOG_ERROR("Target not examined yet");
1785 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1786 LOG_ERROR("Failed to Configure semihosting");
1790 /* FIXME never let that "catch" be dropped! (???) */
1791 semihosting->is_active = is_active;
1794 command_print(CMD, "semihosting is %s",
1795 semihosting->is_active
1796 ? "enabled" : "disabled");
1801 COMMAND_HANDLER(handle_common_semihosting_redirect_command)
1803 struct target *target = get_current_target(CMD_CTX);
1806 LOG_ERROR("No target selected");
1810 struct semihosting *semihosting = target->semihosting;
1812 command_print(CMD, "semihosting not supported for current target");
1816 if (!semihosting->is_active) {
1817 command_print(CMD, "semihosting not yet enabled for current target");
1821 enum semihosting_redirect_config cfg;
1825 return ERROR_COMMAND_SYNTAX_ERROR;
1827 if (strcmp(CMD_ARGV[0], "disable") == 0) {
1828 cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1830 return ERROR_COMMAND_SYNTAX_ERROR;
1831 } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
1832 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1833 return ERROR_COMMAND_SYNTAX_ERROR;
1837 cfg = SEMIHOSTING_REDIRECT_CFG_ALL;
1838 if (CMD_ARGC == 3) {
1839 if (strcmp(CMD_ARGV[2], "debug") == 0)
1840 cfg = SEMIHOSTING_REDIRECT_CFG_DEBUG;
1841 else if (strcmp(CMD_ARGV[2], "stdio") == 0)
1842 cfg = SEMIHOSTING_REDIRECT_CFG_STDIO;
1843 else if (strcmp(CMD_ARGV[2], "all") != 0)
1844 return ERROR_COMMAND_SYNTAX_ERROR;
1847 return ERROR_COMMAND_SYNTAX_ERROR;
1850 semihosting_tcp_close_cnx(semihosting);
1851 semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1853 if (cfg != SEMIHOSTING_REDIRECT_CFG_NONE) {
1854 struct semihosting_tcp_service *service =
1855 calloc(1, sizeof(struct semihosting_tcp_service));
1857 LOG_ERROR("Failed to allocate semihosting TCP service.");
1861 service->semihosting = semihosting;
1863 service->name = alloc_printf("%s semihosting service", target_name(target));
1864 if (!service->name) {
1865 LOG_ERROR("Out of memory");
1870 int ret = add_service(&semihosting_service_driver,
1873 if (ret != ERROR_OK) {
1874 LOG_ERROR("failed to initialize %s", service->name);
1875 free(service->name);
1881 semihosting->redirect_cfg = cfg;
1886 COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1888 struct target *target = get_current_target(CMD_CTX);
1891 LOG_ERROR("No target selected");
1895 struct semihosting *semihosting = target->semihosting;
1897 command_print(CMD, "semihosting not supported for current target");
1901 if (!semihosting->is_active) {
1902 command_print(CMD, "semihosting not yet enabled for current target");
1907 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1909 command_print(CMD, "semihosting fileio is %s",
1910 semihosting->is_fileio
1911 ? "enabled" : "disabled");
1916 COMMAND_HANDLER(handle_common_semihosting_cmdline)
1918 struct target *target = get_current_target(CMD_CTX);
1922 LOG_ERROR("No target selected");
1926 struct semihosting *semihosting = target->semihosting;
1928 command_print(CMD, "semihosting not supported for current target");
1932 free(semihosting->cmdline);
1933 semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1935 for (i = 1; i < CMD_ARGC; i++) {
1936 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1939 free(semihosting->cmdline);
1940 semihosting->cmdline = cmdline;
1943 command_print(CMD, "semihosting command line is [%s]",
1944 semihosting->cmdline);
1949 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1951 struct target *target = get_current_target(CMD_CTX);
1954 LOG_ERROR("No target selected");
1958 struct semihosting *semihosting = target->semihosting;
1960 command_print(CMD, "semihosting not supported for current target");
1964 if (!semihosting->is_active) {
1965 command_print(CMD, "semihosting not yet enabled for current target");
1970 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
1972 command_print(CMD, "semihosting resumable exit is %s",
1973 semihosting->has_resumable_exit
1974 ? "enabled" : "disabled");
1979 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
1981 struct target *target = get_current_target(CMD_CTX);
1982 struct semihosting *semihosting = target->semihosting;
1985 return ERROR_COMMAND_SYNTAX_ERROR;
1987 if (!semihosting->is_active) {
1988 LOG_ERROR("semihosting not yet enabled for current target");
1992 if (!semihosting_user_op_params) {
1993 LOG_ERROR("This command is usable only from a registered user "
1994 "semihosting event callback.");
1998 command_print_sameline(CMD, "%s", semihosting_user_op_params);
2003 COMMAND_HANDLER(handle_common_semihosting_basedir_command)
2005 struct target *target = get_current_target(CMD_CTX);
2008 return ERROR_COMMAND_SYNTAX_ERROR;
2011 LOG_ERROR("No target selected");
2015 struct semihosting *semihosting = target->semihosting;
2017 command_print(CMD, "semihosting not supported for current target");
2021 if (!semihosting->is_active) {
2022 command_print(CMD, "semihosting not yet enabled for current target");
2027 free(semihosting->basedir);
2028 semihosting->basedir = strdup(CMD_ARGV[0]);
2029 if (!semihosting->basedir) {
2030 command_print(CMD, "semihosting failed to allocate memory for basedir!");
2035 command_print(CMD, "semihosting base dir: %s",
2036 semihosting->basedir ? semihosting->basedir : "");
2041 const struct command_registration semihosting_common_handlers[] = {
2043 .name = "semihosting",
2044 .handler = handle_common_semihosting_command,
2045 .mode = COMMAND_EXEC,
2046 .usage = "['enable'|'disable']",
2047 .help = "activate support for semihosting operations",
2050 .name = "semihosting_redirect",
2051 .handler = handle_common_semihosting_redirect_command,
2052 .mode = COMMAND_EXEC,
2053 .usage = "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2054 .help = "redirect semihosting IO",
2057 .name = "semihosting_cmdline",
2058 .handler = handle_common_semihosting_cmdline,
2059 .mode = COMMAND_EXEC,
2060 .usage = "arguments",
2061 .help = "command line arguments to be passed to program",
2064 .name = "semihosting_fileio",
2065 .handler = handle_common_semihosting_fileio_command,
2066 .mode = COMMAND_EXEC,
2067 .usage = "['enable'|'disable']",
2068 .help = "activate support for semihosting fileio operations",
2071 .name = "semihosting_resexit",
2072 .handler = handle_common_semihosting_resumable_exit_command,
2073 .mode = COMMAND_EXEC,
2074 .usage = "['enable'|'disable']",
2075 .help = "activate support for semihosting resumable exit",
2078 .name = "semihosting_read_user_param",
2079 .handler = handle_common_semihosting_read_user_param_command,
2080 .mode = COMMAND_EXEC,
2082 .help = "read parameters in semihosting-user-cmd-0x10X callbacks",
2085 .name = "semihosting_basedir",
2086 .handler = handle_common_semihosting_basedir_command,
2087 .mode = COMMAND_EXEC,
2089 .help = "set the base directory for semihosting I/O operations",
2091 COMMAND_REGISTRATION_DONE