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>
42 #include <server/gdb_server.h>
46 * It is not possible to use O_... flags defined in sys/stat.h because they
47 * are not guaranteed to match the values defined by the GDB Remote Protocol.
48 * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
51 TARGET_O_RDONLY
= 0x000,
52 TARGET_O_WRONLY
= 0x001,
53 TARGET_O_RDWR
= 0x002,
54 TARGET_O_APPEND
= 0x008,
55 TARGET_O_CREAT
= 0x200,
56 TARGET_O_TRUNC
= 0x400,
57 /* O_EXCL=0x800 is not required in this implementation. */
60 /* GDB remote protocol does not differentiate between text and binary open modes. */
61 static const int open_gdb_modeflags
[12] = {
66 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
67 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
68 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
69 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
70 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
71 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
72 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
,
73 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
76 static const int open_host_modeflags
[12] = {
81 O_WRONLY
| O_CREAT
| O_TRUNC
,
82 O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
83 O_RDWR
| O_CREAT
| O_TRUNC
,
84 O_RDWR
| O_CREAT
| O_TRUNC
| O_BINARY
,
85 O_WRONLY
| O_CREAT
| O_APPEND
,
86 O_WRONLY
| O_CREAT
| O_APPEND
| O_BINARY
,
87 O_RDWR
| O_CREAT
| O_APPEND
,
88 O_RDWR
| O_CREAT
| O_APPEND
| O_BINARY
91 static int semihosting_common_fileio_info(struct target
*target
,
92 struct gdb_fileio_info
*fileio_info
);
93 static int semihosting_common_fileio_end(struct target
*target
, int result
,
94 int fileio_errno
, bool ctrl_c
);
97 * Initialize common semihosting support.
99 * @param target Pointer to the target to initialize.
102 * @return An error status if there is a problem during initialization.
104 int semihosting_common_init(struct target
*target
, void *setup
,
109 target
->fileio_info
= malloc(sizeof(*target
->fileio_info
));
110 if (!target
->fileio_info
) {
111 LOG_ERROR("out of memory");
114 memset(target
->fileio_info
, 0, sizeof(*target
->fileio_info
));
116 struct semihosting
*semihosting
;
117 semihosting
= malloc(sizeof(*target
->semihosting
));
119 LOG_ERROR("out of memory");
123 semihosting
->is_active
= false;
124 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
125 semihosting
->tcp_connection
= NULL
;
126 semihosting
->stdin_fd
= -1;
127 semihosting
->stdout_fd
= -1;
128 semihosting
->stderr_fd
= -1;
129 semihosting
->is_fileio
= false;
130 semihosting
->hit_fileio
= false;
131 semihosting
->is_resumable
= false;
132 semihosting
->has_resumable_exit
= false;
133 semihosting
->word_size_bytes
= 0;
134 semihosting
->op
= -1;
135 semihosting
->param
= 0;
136 semihosting
->result
= -1;
137 semihosting
->sys_errno
= -1;
138 semihosting
->cmdline
= NULL
;
139 semihosting
->basedir
= NULL
;
141 /* If possible, update it in setup(). */
142 semihosting
->setup_time
= clock();
144 semihosting
->setup
= setup
;
145 semihosting
->post_result
= post_result
;
146 semihosting
->user_command_extension
= NULL
;
148 target
->semihosting
= semihosting
;
150 target
->type
->get_gdb_fileio_info
= semihosting_common_fileio_info
;
151 target
->type
->gdb_fileio_end
= semihosting_common_fileio_end
;
156 struct semihosting_tcp_service
{
157 struct semihosting
*semihosting
;
162 static bool semihosting_is_redirected(struct semihosting
*semihosting
, int fd
)
164 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_NONE
)
167 bool is_read_op
= false;
169 switch (semihosting
->op
) {
170 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
171 case SEMIHOSTING_SYS_READC
:
174 case SEMIHOSTING_SYS_WRITEC
:
175 case SEMIHOSTING_SYS_WRITE0
:
176 /* debug operations are redirected when CFG is either DEBUG or ALL */
177 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_STDIO
)
181 /* check stdio semihosting operations: READ and WRITE */
182 case SEMIHOSTING_SYS_READ
:
185 case SEMIHOSTING_SYS_WRITE
:
186 /* stdio operations are redirected when CFG is either STDIO or ALL */
187 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_DEBUG
)
196 return fd
== semihosting
->stdin_fd
;
198 /* write operation */
199 return fd
== semihosting
->stdout_fd
|| fd
== semihosting
->stderr_fd
;
202 static ssize_t
semihosting_redirect_write(struct semihosting
*semihosting
, void *buf
, int size
)
204 if (!semihosting
->tcp_connection
) {
205 LOG_ERROR("No connected TCP client for semihosting");
206 semihosting
->sys_errno
= EBADF
; /* Bad file number */
210 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
212 int retval
= connection_write(semihosting
->tcp_connection
, buf
, size
);
215 log_socket_error(service
->name
);
220 static ssize_t
semihosting_write(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
222 if (semihosting_is_redirected(semihosting
, fd
))
223 return semihosting_redirect_write(semihosting
, buf
, size
);
226 return write(fd
, buf
, size
);
229 static ssize_t
semihosting_redirect_read(struct semihosting
*semihosting
, void *buf
, int size
)
231 if (!semihosting
->tcp_connection
) {
232 LOG_ERROR("No connected TCP client for semihosting");
233 semihosting
->sys_errno
= EBADF
; /* Bad file number */
237 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
239 service
->error
= ERROR_OK
;
240 semihosting
->tcp_connection
->input_pending
= true;
242 int retval
= connection_read(semihosting
->tcp_connection
, buf
, size
);
245 service
->error
= ERROR_SERVER_REMOTE_CLOSED
;
248 log_socket_error(service
->name
);
250 semihosting
->tcp_connection
->input_pending
= false;
255 static inline int semihosting_putchar(struct semihosting
*semihosting
, int fd
, int c
)
257 if (semihosting_is_redirected(semihosting
, fd
))
258 return semihosting_redirect_write(semihosting
, &c
, 1);
260 /* default putchar */
264 static inline ssize_t
semihosting_read(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
266 if (semihosting_is_redirected(semihosting
, fd
))
267 return semihosting_redirect_read(semihosting
, buf
, size
);
270 ssize_t result
= read(fd
, buf
, size
);
271 semihosting
->sys_errno
= errno
;
276 static inline int semihosting_getchar(struct semihosting
*semihosting
, int fd
)
278 if (semihosting_is_redirected(semihosting
, fd
)) {
281 if (semihosting_redirect_read(semihosting
, &c
, 1) > 0)
287 /* default getchar */
292 * User operation parameter string storage buffer. Contains valid data when the
293 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
295 static char *semihosting_user_op_params
;
298 * Portable implementation of ARM semihosting calls.
299 * Performs the currently pending semihosting operation
300 * encoded in target->semihosting.
302 int semihosting_common(struct target
*target
)
304 struct semihosting
*semihosting
= target
->semihosting
;
306 /* Silently ignore if the semihosting field was not set. */
310 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
313 * By default return an error.
314 * The actual result must be set by each function
316 semihosting
->result
= -1;
318 /* Most operations are resumable, except the two exit calls. */
319 semihosting
->is_resumable
= true;
323 /* Enough space to hold 4 long words. */
326 LOG_DEBUG("op=0x%x, param=0x%" PRIx64
, semihosting
->op
,
329 switch (semihosting
->op
) {
331 case SEMIHOSTING_SYS_CLOCK
: /* 0x10 */
333 * Returns the number of centiseconds (hundredths of a second)
334 * since the execution started.
336 * Values returned can be of limited use for some benchmarking
337 * purposes because of communication overhead or other
338 * agent-specific factors. For example, with a debug hardware
339 * unit the request is passed back to the host for execution.
340 * This can lead to unpredictable delays in transmission and
341 * process scheduling.
343 * Use this function to calculate time intervals, by calculating
344 * differences between intervals with and without the code
345 * sequence to be timed.
348 * The PARAMETER REGISTER must contain 0. There are no other
352 * On exit, the RETURN REGISTER contains:
353 * - The number of centiseconds since some arbitrary start
354 * point, if the call is successful.
355 * - –1 if the call is not successful. For example, because
356 * of a communications error.
359 clock_t delta
= clock() - semihosting
->setup_time
;
361 semihosting
->result
= delta
/ (CLOCKS_PER_SEC
/ 100);
365 case SEMIHOSTING_SYS_CLOSE
: /* 0x02 */
367 * Closes a file on the host system. The handle must reference
368 * a file that was opened with SYS_OPEN.
371 * On entry, the PARAMETER REGISTER contains a pointer to a
372 * one-field argument block:
373 * - field 1 Contains a handle for an open file.
376 * On exit, the RETURN REGISTER contains:
377 * - 0 if the call is successful
378 * - –1 if the call is not successful.
380 retval
= semihosting_read_fields(target
, 1, fields
);
381 if (retval
!= ERROR_OK
)
384 int fd
= semihosting_get_field(target
, 0, fields
);
385 /* Do not allow to close OpenOCD's own standard streams */
386 if (fd
== 0 || fd
== 1 || fd
== 2) {
387 LOG_DEBUG("ignoring semihosting attempt to close %s",
388 (fd
== 0) ? "stdin" :
389 (fd
== 1) ? "stdout" : "stderr");
390 /* Just pretend success */
391 if (semihosting
->is_fileio
) {
392 semihosting
->result
= 0;
394 semihosting
->result
= 0;
395 semihosting
->sys_errno
= 0;
399 /* Close the descriptor */
400 if (semihosting
->is_fileio
) {
401 semihosting
->hit_fileio
= true;
402 fileio_info
->identifier
= "close";
403 fileio_info
->param_1
= fd
;
405 semihosting
->result
= close(fd
);
406 semihosting
->sys_errno
= errno
;
407 LOG_DEBUG("close(%d)=%" PRId64
, fd
, semihosting
->result
);
412 case SEMIHOSTING_SYS_ERRNO
: /* 0x13 */
414 * Returns the value of the C library errno variable that is
415 * associated with the semihosting implementation. The errno
416 * variable can be set by a number of C library semihosted
417 * functions, including:
425 * Whether errno is set or not, and to what value, is entirely
426 * host-specific, except where the ISO C standard defines the
430 * There are no parameters. The PARAMETER REGISTER must be 0.
433 * On exit, the RETURN REGISTER contains the value of the C
434 * library errno variable.
436 semihosting
->result
= semihosting
->sys_errno
;
439 case SEMIHOSTING_SYS_EXIT
: /* 0x18 */
441 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
442 * previous versions of the documentation.
444 * An application calls this operation to report an exception
445 * to the debugger directly. The most common use is to report
446 * that execution has completed, using ADP_Stopped_ApplicationExit.
448 * Note: This semihosting operation provides no means for 32-bit
449 * callers to indicate an application exit with a specified exit
450 * code. Semihosting callers may prefer to check for the presence
451 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
452 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
456 * On entry, the PARAMETER register is set to a reason code
457 * describing the cause of the trap. Not all semihosting client
458 * implementations will necessarily trap every corresponding
459 * event. Important reason codes are:
461 * - ADP_Stopped_ApplicationExit 0x20026
462 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
465 * On entry, the PARAMETER REGISTER contains a pointer to a
466 * two-field argument block:
467 * - field 1 The exception type, which is one of the set of
468 * reason codes in the above tables.
469 * - field 2 A subcode, whose meaning depends on the reason
471 * In particular, if field 1 is ADP_Stopped_ApplicationExit
472 * then field 2 is an exit status code, as passed to the C
473 * standard library exit() function. A simulator receiving
474 * this request must notify a connected debugger, if present,
475 * and then exit with the specified status.
478 * No return is expected from these calls. However, it is
479 * possible for the debugger to request that the application
480 * continues by performing an RDI_Execute request or equivalent.
481 * In this case, execution continues with the registers as they
482 * were on entry to the operation, or as subsequently modified
485 if (semihosting
->word_size_bytes
== 8) {
486 retval
= semihosting_read_fields(target
, 2, fields
);
487 if (retval
!= ERROR_OK
)
490 int type
= semihosting_get_field(target
, 0, fields
);
491 int code
= semihosting_get_field(target
, 1, fields
);
493 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
494 if (!gdb_get_actual_connections())
498 "semihosting: *** application exited with %d ***\n",
503 "semihosting: application exception %#x\n",
508 if (semihosting
->param
== ADP_STOPPED_APPLICATION_EXIT
) {
509 if (!gdb_get_actual_connections())
513 "semihosting: *** application exited normally ***\n");
515 } else if (semihosting
->param
== ADP_STOPPED_RUN_TIME_ERROR
) {
516 /* Chosen more or less arbitrarily to have a nicer message,
517 * otherwise all other return the same exit code 1. */
518 if (!gdb_get_actual_connections())
522 "semihosting: *** application exited with error ***\n");
525 if (!gdb_get_actual_connections())
529 "semihosting: application exception %#x\n",
530 (unsigned) semihosting
->param
);
534 if (!semihosting
->has_resumable_exit
) {
535 semihosting
->is_resumable
= false;
536 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
540 case SEMIHOSTING_SYS_EXIT_EXTENDED
: /* 0x20 */
542 * This operation is only supported if the semihosting extension
543 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
544 * reported using feature byte 0, bit 0. If this extension is
545 * supported, then the implementation provides a means to
546 * report a normal exit with a nonzero exit status in both 32-bit
547 * and 64-bit semihosting APIs.
549 * The implementation must provide the semihosting call
550 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
552 * SYS_EXIT_EXTENDED is used by an application to report an
553 * exception or exit to the debugger directly. The most common
554 * use is to report that execution has completed, using
555 * ADP_Stopped_ApplicationExit.
558 * On entry, the PARAMETER REGISTER contains a pointer to a
559 * two-field argument block:
560 * - field 1 The exception type, which should be one of the set
561 * of reason codes that are documented for the SYS_EXIT
562 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
563 * - field 2 A subcode, whose meaning depends on the reason
564 * code in field 1. In particular, if field 1 is
565 * ADP_Stopped_ApplicationExit then field 2 is an exit status
566 * code, as passed to the C standard library exit() function.
567 * A simulator receiving this request must notify a connected
568 * debugger, if present, and then exit with the specified status.
571 * No return is expected from these calls.
573 * For the A64 API, this call is identical to the behavior of
574 * the mandatory SYS_EXIT (0x18) call. If this extension is
575 * supported, then both calls must be implemented.
577 retval
= semihosting_read_fields(target
, 2, fields
);
578 if (retval
!= ERROR_OK
)
581 int type
= semihosting_get_field(target
, 0, fields
);
582 int code
= semihosting_get_field(target
, 1, fields
);
584 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
585 if (!gdb_get_actual_connections())
589 "semihosting: *** application exited with %d ***\n",
593 fprintf(stderr
, "semihosting: exception %#x\n",
597 if (!semihosting
->has_resumable_exit
) {
598 semihosting
->is_resumable
= false;
599 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
603 case SEMIHOSTING_SYS_FLEN
: /* 0x0C */
605 * Returns the length of a specified file.
608 * On entry, the PARAMETER REGISTER contains a pointer to a
609 * one-field argument block:
610 * - field 1 A handle for a previously opened, seekable file
614 * On exit, the RETURN REGISTER contains:
615 * - The current length of the file object, if the call is
617 * - –1 if an error occurs.
619 if (semihosting
->is_fileio
) {
620 semihosting
->result
= -1;
621 semihosting
->sys_errno
= EINVAL
;
623 retval
= semihosting_read_fields(target
, 1, fields
);
624 if (retval
!= ERROR_OK
)
627 int fd
= semihosting_get_field(target
, 0, fields
);
629 semihosting
->result
= fstat(fd
, &buf
);
630 if (semihosting
->result
== -1) {
631 semihosting
->sys_errno
= errno
;
632 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
635 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
636 semihosting
->result
= buf
.st_size
;
640 case SEMIHOSTING_SYS_GET_CMDLINE
: /* 0x15 */
642 * Returns the command line that is used for the call to the
643 * executable, that is, argc and argv.
646 * On entry, the PARAMETER REGISTER points to a two-field data
647 * block to be used for returning the command string and its length:
648 * - field 1 A pointer to a buffer of at least the size that is
649 * specified in field 2.
650 * - field 2 The length of the buffer in bytes.
654 * If the call is successful, then the RETURN REGISTER contains 0,
655 * the PARAMETER REGISTER is unchanged, and the data block is
656 * updated as follows:
657 * - field 1 A pointer to a null-terminated string of the command
659 * - field 2 The length of the string in bytes.
660 * If the call is not successful, then the RETURN REGISTER
663 * Note: The semihosting implementation might impose limits on
664 * the maximum length of the string that can be transferred.
665 * However, the implementation must be able to support a
666 * command-line length of at least 80 bytes.
668 retval
= semihosting_read_fields(target
, 2, fields
);
669 if (retval
!= ERROR_OK
)
672 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
673 size_t size
= semihosting_get_field(target
, 1, fields
);
675 char *arg
= semihosting
->cmdline
?
676 semihosting
->cmdline
: "";
677 uint32_t len
= strlen(arg
) + 1;
679 semihosting
->result
= -1;
681 semihosting_set_field(target
, len
, 1, fields
);
682 retval
= target_write_buffer(target
, addr
, len
,
684 if (retval
!= ERROR_OK
)
686 semihosting
->result
= 0;
688 retval
= semihosting_write_fields(target
, 2, fields
);
689 if (retval
!= ERROR_OK
)
692 LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64
, arg
, semihosting
->result
);
696 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
698 * Returns the system stack and heap parameters.
701 * On entry, the PARAMETER REGISTER contains the address of a
702 * pointer to a four-field data block. The contents of the data
703 * block are filled by the function. The following C-like
704 * pseudocode describes the layout of the block:
713 * On exit, the PARAMETER REGISTER is unchanged and the data
714 * block has been updated.
716 retval
= semihosting_read_fields(target
, 1, fields
);
717 if (retval
!= ERROR_OK
)
720 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
721 /* tell the remote we have no idea */
722 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
723 retval
= target_write_memory(target
, addr
, 4,
724 semihosting
->word_size_bytes
,
726 if (retval
!= ERROR_OK
)
728 semihosting
->result
= 0;
732 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
734 * Determines whether the return code from another semihosting
735 * call is an error status or not.
737 * This call is passed a parameter block containing the error
741 * On entry, the PARAMETER REGISTER contains a pointer to a
742 * one-field data block:
743 * - field 1 The required status word to check.
746 * On exit, the RETURN REGISTER contains:
747 * - 0 if the status field is not an error indication
748 * - A nonzero value if the status field is an error indication.
750 retval
= semihosting_read_fields(target
, 1, fields
);
751 if (retval
!= ERROR_OK
)
754 uint64_t code
= semihosting_get_field(target
, 0, fields
);
755 semihosting
->result
= (code
!= 0);
758 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
760 * Checks whether a file is connected to an interactive device.
763 * On entry, the PARAMETER REGISTER contains a pointer to a
764 * one-field argument block:
765 * field 1 A handle for a previously opened file object.
768 * On exit, the RETURN REGISTER contains:
769 * - 1 if the handle identifies an interactive device.
770 * - 0 if the handle identifies a file.
771 * - A value other than 1 or 0 if an error occurs.
773 if (semihosting
->is_fileio
) {
774 semihosting
->hit_fileio
= true;
775 fileio_info
->identifier
= "isatty";
776 fileio_info
->param_1
= semihosting
->param
;
778 retval
= semihosting_read_fields(target
, 1, fields
);
779 if (retval
!= ERROR_OK
)
781 int fd
= semihosting_get_field(target
, 0, fields
);
782 // isatty() on Windows may return any non-zero value if fd is a terminal
783 semihosting
->result
= isatty(fd
) ? 1 : 0;
784 semihosting
->sys_errno
= errno
;
785 LOG_DEBUG("isatty(%d)=%" PRId64
, fd
, semihosting
->result
);
789 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
791 * Opens a file on the host system.
793 * The file path is specified either as relative to the current
794 * directory of the host process, or absolute, using the path
795 * conventions of the host operating system.
797 * Semihosting implementations must support opening the special
798 * path name :semihosting-features as part of the semihosting
799 * extensions reporting mechanism.
801 * ARM targets interpret the special path name :tt as meaning
802 * the console input stream, for an open-read or the console
803 * output stream, for an open-write. Opening these streams is
804 * performed as part of the standard startup code for those
805 * applications that reference the C stdio streams. The
806 * semihosting extension SH_EXT_STDOUT_STDERR allows the
807 * semihosting caller to open separate output streams
808 * corresponding to stdout and stderr. This extension is
809 * reported using feature byte 0, bit 1. Use SYS_OPEN with
810 * the special path name :semihosting-features to access the
813 * If this extension is supported, the implementation must
814 * support the following additional semantics to SYS_OPEN:
815 * - If the special path name :tt is opened with an fopen
816 * mode requesting write access (w, wb, w+, or w+b), then
817 * this is a request to open stdout.
818 * - If the special path name :tt is opened with a mode
819 * requesting append access (a, ab, a+, or a+b), then this is
820 * a request to open stderr.
823 * On entry, the PARAMETER REGISTER contains a pointer to a
824 * three-field argument block:
825 * - field 1 A pointer to a null-terminated string containing
826 * a file or device name.
827 * - field 2 An integer that specifies the file opening mode.
828 * - field 3 An integer that gives the length of the string
829 * pointed to by field 1.
831 * The length does not include the terminating null character
832 * that must be present.
835 * On exit, the RETURN REGISTER contains:
836 * - A nonzero handle if the call is successful.
837 * - –1 if the call is not successful.
839 retval
= semihosting_read_fields(target
, 3, fields
);
840 if (retval
!= ERROR_OK
)
843 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
844 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
845 size_t len
= semihosting_get_field(target
, 2, fields
);
848 semihosting
->result
= -1;
849 semihosting
->sys_errno
= EINVAL
;
852 size_t basedir_len
= semihosting
->basedir
? strlen(semihosting
->basedir
) : 0;
853 uint8_t *fn
= malloc(basedir_len
+ len
+ 2);
855 semihosting
->result
= -1;
856 semihosting
->sys_errno
= ENOMEM
;
858 if (basedir_len
> 0) {
859 strcpy((char *)fn
, semihosting
->basedir
);
860 if (fn
[basedir_len
- 1] != '/')
861 fn
[basedir_len
++] = '/';
863 retval
= target_read_memory(target
, addr
, 1, len
, fn
+ basedir_len
);
864 if (retval
!= ERROR_OK
) {
868 fn
[basedir_len
+ len
] = 0;
869 /* TODO: implement the :semihosting-features special file.
871 if (semihosting
->is_fileio
) {
872 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
873 semihosting
->result
= -1;
874 semihosting
->sys_errno
= EINVAL
;
875 } else if (strcmp((char *)fn
, ":tt") == 0) {
877 semihosting
->result
= 0;
879 semihosting
->result
= 1;
881 semihosting
->result
= 2;
883 semihosting
->result
= -1;
885 semihosting
->hit_fileio
= true;
886 fileio_info
->identifier
= "open";
887 fileio_info
->param_1
= addr
;
888 fileio_info
->param_2
= len
;
889 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
890 fileio_info
->param_4
= 0644;
893 if (strcmp((char *)fn
, ":tt") == 0) {
895 * - 0-3 ("r") for stdin,
896 * - 4-7 ("w") for stdout,
897 * - 8-11 ("a") for stderr */
899 int fd
= dup(STDIN_FILENO
);
900 semihosting
->result
= fd
;
901 semihosting
->stdin_fd
= fd
;
902 semihosting
->sys_errno
= errno
;
903 LOG_DEBUG("dup(STDIN)=%" PRId64
, semihosting
->result
);
904 } else if (mode
< 8) {
905 int fd
= dup(STDOUT_FILENO
);
906 semihosting
->result
= fd
;
907 semihosting
->stdout_fd
= fd
;
908 semihosting
->sys_errno
= errno
;
909 LOG_DEBUG("dup(STDOUT)=%" PRId64
, semihosting
->result
);
911 int fd
= dup(STDERR_FILENO
);
912 semihosting
->result
= fd
;
913 semihosting
->stderr_fd
= fd
;
914 semihosting
->sys_errno
= errno
;
915 LOG_DEBUG("dup(STDERR)=%" PRId64
, semihosting
->result
);
918 /* cygwin requires the permission setting
919 * otherwise it will fail to reopen a previously
921 semihosting
->result
= open((char *)fn
,
922 open_host_modeflags
[mode
],
924 semihosting
->sys_errno
= errno
;
925 LOG_DEBUG("open('%s')=%" PRId64
, fn
, semihosting
->result
);
933 case SEMIHOSTING_SYS_READ
: /* 0x06 */
935 * Reads the contents of a file into a buffer. The file position
936 * is specified either:
937 * - Explicitly by a SYS_SEEK.
938 * - Implicitly one byte beyond the previous SYS_READ or
941 * The file position is at the start of the file when it is
942 * opened, and is lost when the file is closed. Perform the
943 * file operation as a single action whenever possible. For
944 * example, do not split a read of 16KB into four 4KB chunks
945 * unless there is no alternative.
948 * On entry, the PARAMETER REGISTER contains a pointer to a
949 * three-field data block:
950 * - field 1 Contains a handle for a file previously opened
952 * - field 2 Points to a buffer.
953 * - field 3 Contains the number of bytes to read to the buffer
957 * On exit, the RETURN REGISTER contains the number of bytes not
958 * filled in the buffer (buffer_length - bytes_read) as follows:
959 * - If the RETURN REGISTER is 0, the entire buffer was
960 * successfully filled.
961 * - If the RETURN REGISTER is the same as field 3, no bytes
962 * were read (EOF can be assumed).
963 * - If the RETURN REGISTER contains a value smaller than
964 * field 3, the read succeeded but the buffer was only partly
965 * filled. For interactive devices, this is the most common
968 retval
= semihosting_read_fields(target
, 3, fields
);
969 if (retval
!= ERROR_OK
)
972 int fd
= semihosting_get_field(target
, 0, fields
);
973 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
974 size_t len
= semihosting_get_field(target
, 2, fields
);
975 if (semihosting
->is_fileio
) {
976 semihosting
->hit_fileio
= true;
977 fileio_info
->identifier
= "read";
978 fileio_info
->param_1
= fd
;
979 fileio_info
->param_2
= addr
;
980 fileio_info
->param_3
= len
;
982 uint8_t *buf
= malloc(len
);
984 semihosting
->result
= -1;
985 semihosting
->sys_errno
= ENOMEM
;
987 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
988 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
992 semihosting
->result
);
993 if (semihosting
->result
>= 0) {
994 retval
= target_write_buffer(target
, addr
,
997 if (retval
!= ERROR_OK
) {
1001 /* the number of bytes NOT filled in */
1002 semihosting
->result
= len
-
1003 semihosting
->result
;
1011 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1013 * Reads a byte from the console.
1016 * The PARAMETER REGISTER must contain 0. There are no other
1017 * parameters or values possible.
1020 * On exit, the RETURN REGISTER contains the byte read from
1023 if (semihosting
->is_fileio
) {
1024 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1027 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1028 LOG_DEBUG("getchar()=%" PRId64
, semihosting
->result
);
1031 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1033 * Deletes a specified file on the host filing system.
1036 * On entry, the PARAMETER REGISTER contains a pointer to a
1037 * two-field argument block:
1038 * - field 1 Points to a null-terminated string that gives the
1039 * path name of the file to be deleted.
1040 * - field 2 The length of the string.
1043 * On exit, the RETURN REGISTER contains:
1044 * - 0 if the delete is successful
1045 * - A nonzero, host-specific error code if the delete fails.
1047 retval
= semihosting_read_fields(target
, 2, fields
);
1048 if (retval
!= ERROR_OK
)
1051 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1052 size_t len
= semihosting_get_field(target
, 1, fields
);
1053 if (semihosting
->is_fileio
) {
1054 semihosting
->hit_fileio
= true;
1055 fileio_info
->identifier
= "unlink";
1056 fileio_info
->param_1
= addr
;
1057 fileio_info
->param_2
= len
;
1059 uint8_t *fn
= malloc(len
+1);
1061 semihosting
->result
= -1;
1062 semihosting
->sys_errno
= ENOMEM
;
1065 target_read_memory(target
, addr
, 1, len
,
1067 if (retval
!= ERROR_OK
) {
1072 semihosting
->result
= remove((char *)fn
);
1073 semihosting
->sys_errno
= errno
;
1074 LOG_DEBUG("remove('%s')=%" PRId64
, fn
, semihosting
->result
);
1082 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1084 * Renames a specified file.
1087 * On entry, the PARAMETER REGISTER contains a pointer to a
1088 * four-field data block:
1089 * - field 1 A pointer to the name of the old file.
1090 * - field 2 The length of the old filename.
1091 * - field 3 A pointer to the new filename.
1092 * - field 4 The length of the new filename. Both strings are
1096 * On exit, the RETURN REGISTER contains:
1097 * - 0 if the rename is successful.
1098 * - A nonzero, host-specific error code if the rename fails.
1100 retval
= semihosting_read_fields(target
, 4, fields
);
1101 if (retval
!= ERROR_OK
)
1104 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1105 size_t len1
= semihosting_get_field(target
, 1, fields
);
1106 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1107 size_t len2
= semihosting_get_field(target
, 3, fields
);
1108 if (semihosting
->is_fileio
) {
1109 semihosting
->hit_fileio
= true;
1110 fileio_info
->identifier
= "rename";
1111 fileio_info
->param_1
= addr1
;
1112 fileio_info
->param_2
= len1
;
1113 fileio_info
->param_3
= addr2
;
1114 fileio_info
->param_4
= len2
;
1116 uint8_t *fn1
= malloc(len1
+1);
1117 uint8_t *fn2
= malloc(len2
+1);
1121 semihosting
->result
= -1;
1122 semihosting
->sys_errno
= ENOMEM
;
1124 retval
= target_read_memory(target
, addr1
, 1, len1
,
1126 if (retval
!= ERROR_OK
) {
1131 retval
= target_read_memory(target
, addr2
, 1, len2
,
1133 if (retval
!= ERROR_OK
) {
1140 semihosting
->result
= rename((char *)fn1
,
1142 semihosting
->sys_errno
= errno
;
1143 LOG_DEBUG("rename('%s', '%s')=%" PRId64
" %d", fn1
, fn2
, semihosting
->result
, errno
);
1151 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1153 * Seeks to a specified position in a file using an offset
1154 * specified from the start of the file. The file is assumed
1155 * to be a byte array and the offset is given in bytes.
1158 * On entry, the PARAMETER REGISTER contains a pointer to a
1159 * two-field data block:
1160 * - field 1 A handle for a seekable file object.
1161 * - field 2 The absolute byte position to seek to.
1164 * On exit, the RETURN REGISTER contains:
1165 * - 0 if the request is successful.
1166 * - A negative value if the request is not successful.
1167 * Use SYS_ERRNO to read the value of the host errno variable
1168 * describing the error.
1170 * Note: The effect of seeking outside the current extent of
1171 * the file object is undefined.
1173 retval
= semihosting_read_fields(target
, 2, fields
);
1174 if (retval
!= ERROR_OK
)
1177 int fd
= semihosting_get_field(target
, 0, fields
);
1178 off_t pos
= semihosting_get_field(target
, 1, fields
);
1179 if (semihosting
->is_fileio
) {
1180 semihosting
->hit_fileio
= true;
1181 fileio_info
->identifier
= "lseek";
1182 fileio_info
->param_1
= fd
;
1183 fileio_info
->param_2
= pos
;
1184 fileio_info
->param_3
= SEEK_SET
;
1186 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1187 semihosting
->sys_errno
= errno
;
1188 LOG_DEBUG("lseek(%d, %d)=%" PRId64
, fd
, (int)pos
, semihosting
->result
);
1189 if (semihosting
->result
== pos
)
1190 semihosting
->result
= 0;
1195 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1197 * Passes a command to the host command-line interpreter.
1198 * This enables you to execute a system command such as dir,
1199 * ls, or pwd. The terminal I/O is on the host, and is not
1200 * visible to the target.
1203 * On entry, the PARAMETER REGISTER contains a pointer to a
1204 * two-field argument block:
1205 * - field 1 Points to a string to be passed to the host
1206 * command-line interpreter.
1207 * - field 2 The length of the string.
1210 * On exit, the RETURN REGISTER contains the return status.
1213 /* Provide SYS_SYSTEM functionality. Uses the
1214 * libc system command, there may be a reason *NOT*
1215 * to use this, but as I can't think of one, I
1216 * implemented it this way.
1218 retval
= semihosting_read_fields(target
, 2, fields
);
1219 if (retval
!= ERROR_OK
)
1222 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1223 size_t len
= semihosting_get_field(target
, 1, fields
);
1224 if (semihosting
->is_fileio
) {
1225 semihosting
->hit_fileio
= true;
1226 fileio_info
->identifier
= "system";
1227 fileio_info
->param_1
= addr
;
1228 fileio_info
->param_2
= len
;
1230 uint8_t *cmd
= malloc(len
+1);
1232 semihosting
->result
= -1;
1233 semihosting
->sys_errno
= ENOMEM
;
1235 retval
= target_read_memory(target
,
1240 if (retval
!= ERROR_OK
) {
1245 semihosting
->result
= system(
1247 LOG_DEBUG("system('%s')=%" PRId64
, cmd
, semihosting
->result
);
1256 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1258 * Returns the number of seconds since 00:00 January 1, 1970.
1259 * This value is real-world time, regardless of any debug agent
1263 * There are no parameters.
1266 * On exit, the RETURN REGISTER contains the number of seconds.
1268 semihosting
->result
= time(NULL
);
1271 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1273 * Writes the contents of a buffer to a specified file at the
1274 * current file position. The file position is specified either:
1275 * - Explicitly, by a SYS_SEEK.
1276 * - Implicitly as one byte beyond the previous SYS_READ or
1277 * SYS_WRITE request.
1279 * The file position is at the start of the file when the file
1280 * is opened, and is lost when the file is closed.
1282 * Perform the file operation as a single action whenever
1283 * possible. For example, do not split a write of 16KB into
1284 * four 4KB chunks unless there is no alternative.
1287 * On entry, the PARAMETER REGISTER contains a pointer to a
1288 * three-field data block:
1289 * - field 1 Contains a handle for a file previously opened
1291 * - field 2 Points to the memory containing the data to be written.
1292 * - field 3 Contains the number of bytes to be written from
1293 * the buffer to the file.
1296 * On exit, the RETURN REGISTER contains:
1297 * - 0 if the call is successful.
1298 * - The number of bytes that are not written, if there is an error.
1300 retval
= semihosting_read_fields(target
, 3, fields
);
1301 if (retval
!= ERROR_OK
)
1304 int fd
= semihosting_get_field(target
, 0, fields
);
1305 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1306 size_t len
= semihosting_get_field(target
, 2, fields
);
1307 if (semihosting
->is_fileio
) {
1308 semihosting
->hit_fileio
= true;
1309 fileio_info
->identifier
= "write";
1310 fileio_info
->param_1
= fd
;
1311 fileio_info
->param_2
= addr
;
1312 fileio_info
->param_3
= len
;
1314 uint8_t *buf
= malloc(len
);
1316 semihosting
->result
= -1;
1317 semihosting
->sys_errno
= ENOMEM
;
1319 retval
= target_read_buffer(target
, addr
, len
, buf
);
1320 if (retval
!= ERROR_OK
) {
1324 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1325 semihosting
->sys_errno
= errno
;
1326 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
1330 semihosting
->result
);
1331 if (semihosting
->result
>= 0) {
1332 /* The number of bytes that are NOT written.
1334 semihosting
->result
= len
-
1335 semihosting
->result
;
1344 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1346 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1347 * to the debug channel. When executed under a semihosting
1348 * debugger, the character appears on the host debugger console.
1351 * On entry, the PARAMETER REGISTER contains a pointer to the
1355 * None. The RETURN REGISTER is corrupted.
1357 if (semihosting
->is_fileio
) {
1358 semihosting
->hit_fileio
= true;
1359 fileio_info
->identifier
= "write";
1360 fileio_info
->param_1
= 1;
1361 fileio_info
->param_2
= semihosting
->param
;
1362 fileio_info
->param_3
= 1;
1364 uint64_t addr
= semihosting
->param
;
1366 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1367 if (retval
!= ERROR_OK
)
1369 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1370 semihosting
->result
= 0;
1374 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1376 * Writes a null-terminated string to the debug channel.
1377 * When executed under a semihosting debugger, the characters
1378 * appear on the host debugger console.
1381 * On entry, the PARAMETER REGISTER contains a pointer to the
1382 * first byte of the string.
1385 * None. The RETURN REGISTER is corrupted.
1387 if (semihosting
->is_fileio
) {
1389 uint64_t addr
= semihosting
->param
;
1392 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1393 if (retval
!= ERROR_OK
)
1399 semihosting
->hit_fileio
= true;
1400 fileio_info
->identifier
= "write";
1401 fileio_info
->param_1
= 1;
1402 fileio_info
->param_2
= semihosting
->param
;
1403 fileio_info
->param_3
= count
;
1405 uint64_t addr
= semihosting
->param
;
1408 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1409 if (retval
!= ERROR_OK
)
1413 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1415 semihosting
->result
= 0;
1419 case SEMIHOSTING_USER_CMD_0X100
... SEMIHOSTING_USER_CMD_0X107
:
1421 * This is a user defined operation (while user cmds 0x100-0x1ff
1422 * are possible, only 0x100-0x107 are currently implemented).
1424 * Reads the user operation parameters from target, then fires the
1425 * corresponding target event. When the target callbacks returned,
1426 * cleans up the command parameter buffer.
1429 * On entry, the PARAMETER REGISTER contains a pointer to a
1430 * two-field data block:
1431 * - field 1 Contains a pointer to the bound command parameter
1433 * - field 2 Contains the command parameter string length
1436 * On exit, the RETURN REGISTER contains the return status.
1438 if (semihosting
->user_command_extension
) {
1439 retval
= semihosting
->user_command_extension(target
);
1440 if (retval
!= ERROR_NOT_IMPLEMENTED
)
1442 /* If custom user command not handled, we are looking for the TCL handler */
1445 assert(!semihosting_user_op_params
);
1446 retval
= semihosting_read_fields(target
, 2, fields
);
1447 if (retval
!= ERROR_OK
) {
1448 LOG_ERROR("Failed to read fields for user defined command"
1449 " op=0x%x", semihosting
->op
);
1453 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1455 size_t len
= semihosting_get_field(target
, 1, fields
);
1456 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1457 LOG_ERROR("The maximum length for user defined command "
1458 "parameter is %u, received length is %zu (op=0x%x)",
1459 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1465 semihosting_user_op_params
= malloc(len
+ 1);
1466 if (!semihosting_user_op_params
)
1468 semihosting_user_op_params
[len
] = 0;
1470 retval
= target_read_buffer(target
, addr
, len
,
1471 (uint8_t *)(semihosting_user_op_params
));
1472 if (retval
!= ERROR_OK
) {
1473 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1475 free(semihosting_user_op_params
);
1476 semihosting_user_op_params
= NULL
;
1480 target_handle_event(target
, semihosting
->op
);
1481 free(semihosting_user_op_params
);
1482 semihosting_user_op_params
= NULL
;
1483 semihosting
->result
= 0;
1486 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1488 * Returns the number of elapsed target ticks since execution
1490 * Use SYS_TICKFREQ to determine the tick frequency.
1493 * On entry, the PARAMETER REGISTER points to a two-field data
1494 * block to be used for returning the number of elapsed ticks:
1495 * - field 1 The least significant field and is at the low address.
1496 * - field 2 The most significant field and is at the high address.
1499 * On entry the PARAMETER REGISTER points to a one-field data
1500 * block to be used for returning the number of elapsed ticks:
1501 * - field 1 The number of elapsed ticks as a 64-bit value.
1505 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1506 * REGISTER is unchanged, and the data block pointed to by the
1507 * PARAMETER REGISTER is filled in with the number of elapsed
1509 * - On failure, the RETURN REGISTER contains -1, and the
1510 * PARAMETER REGISTER contains -1.
1512 * Note: Some semihosting implementations might not support this
1513 * semihosting operation, and they always return -1 in the
1517 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1519 * Returns the tick frequency.
1522 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1525 * On exit, the RETURN REGISTER contains either:
1526 * - The number of ticks per second.
1527 * - –1 if the target does not know the value of one tick.
1529 * Note: Some semihosting implementations might not support
1530 * this semihosting operation, and they always return -1 in the
1534 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1536 * Returns a temporary name for a file identified by a system
1540 * On entry, the PARAMETER REGISTER contains a pointer to a
1541 * three-word argument block:
1542 * - field 1 A pointer to a buffer.
1543 * - field 2 A target identifier for this filename. Its value
1544 * must be an integer in the range 0-255.
1545 * - field 3 Contains the length of the buffer. The length must
1546 * be at least the value of L_tmpnam on the host system.
1549 * On exit, the RETURN REGISTER contains:
1550 * - 0 if the call is successful.
1551 * - –1 if an error occurs.
1553 * The buffer pointed to by the PARAMETER REGISTER contains
1554 * the filename, prefixed with a suitable directory name.
1555 * If you use the same target identifier again, the same
1556 * filename is returned.
1558 * Note: The returned string must be null-terminated.
1562 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1563 (unsigned) semihosting
->op
);
1564 semihosting
->result
= -1;
1565 semihosting
->sys_errno
= ENOTSUP
;
1568 if (!semihosting
->hit_fileio
) {
1569 retval
= semihosting
->post_result(target
);
1570 if (retval
!= ERROR_OK
) {
1571 LOG_ERROR("Failed to post semihosting result");
1579 /* -------------------------------------------------------------------------
1580 * Local functions. */
1582 static int semihosting_common_fileio_info(struct target
*target
,
1583 struct gdb_fileio_info
*fileio_info
)
1585 struct semihosting
*semihosting
= target
->semihosting
;
1590 * To avoid unnecessary duplication, semihosting prepares the
1591 * fileio_info structure out-of-band when the target halts. See
1592 * do_semihosting for more detail.
1594 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1600 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1601 int fileio_errno
, bool ctrl_c
)
1603 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1604 struct semihosting
*semihosting
= target
->semihosting
;
1608 /* clear pending status */
1609 semihosting
->hit_fileio
= false;
1611 semihosting
->result
= result
;
1612 semihosting
->sys_errno
= fileio_errno
;
1615 * Some fileio results do not match up with what the semihosting
1616 * operation expects; for these operations, we munge the results
1619 switch (semihosting
->op
) {
1620 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1621 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1623 semihosting
->result
= fileio_info
->param_3
; /* Zero bytes read/written. */
1625 semihosting
->result
= (int64_t)fileio_info
->param_3
- result
;
1628 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1630 semihosting
->result
= 0;
1634 return semihosting
->post_result(target
);
1637 /* -------------------------------------------------------------------------
1638 * Utility functions. */
1641 * Read all fields of a command from target to buffer.
1643 int semihosting_read_fields(struct target
*target
, size_t number
,
1646 struct semihosting
*semihosting
= target
->semihosting
;
1647 /* Use 4-byte multiples to trigger fast memory access. */
1648 return target_read_memory(target
, semihosting
->param
, 4,
1649 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1653 * Write all fields of a command from buffer to target.
1655 int semihosting_write_fields(struct target
*target
, size_t number
,
1658 struct semihosting
*semihosting
= target
->semihosting
;
1659 /* Use 4-byte multiples to trigger fast memory access. */
1660 return target_write_memory(target
, semihosting
->param
, 4,
1661 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1665 * Extract a field from the buffer, considering register size and endianness.
1667 uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1670 struct semihosting
*semihosting
= target
->semihosting
;
1671 if (semihosting
->word_size_bytes
== 8)
1672 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1674 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1678 * Store a field in the buffer, considering register size and endianness.
1680 void semihosting_set_field(struct target
*target
, uint64_t value
,
1684 struct semihosting
*semihosting
= target
->semihosting
;
1685 if (semihosting
->word_size_bytes
== 8)
1686 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1688 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1691 /* -------------------------------------------------------------------------
1692 * Semihosting redirect over TCP structs and functions */
1694 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1696 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1697 service
->semihosting
->tcp_connection
= connection
;
1702 static int semihosting_service_input_handler(struct connection
*connection
)
1704 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1706 if (!connection
->input_pending
) {
1707 /* consume received data, not for semihosting IO */
1708 const int buf_len
= 100;
1710 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1712 if (bytes_read
== 0) {
1713 return ERROR_SERVER_REMOTE_CLOSED
;
1714 } else if (bytes_read
== -1) {
1715 LOG_ERROR("error during read: %s", strerror(errno
));
1716 return ERROR_SERVER_REMOTE_CLOSED
;
1718 } else if (service
->error
!= ERROR_OK
) {
1719 return ERROR_SERVER_REMOTE_CLOSED
;
1725 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1727 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1729 free(service
->name
);
1736 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1738 if (!semihosting
->tcp_connection
)
1741 struct service
*service
= semihosting
->tcp_connection
->service
;
1742 remove_service(service
->name
, service
->port
);
1743 semihosting
->tcp_connection
= NULL
;
1747 static const struct service_driver semihosting_service_driver
= {
1748 .name
= "semihosting",
1749 .new_connection_during_keep_alive_handler
= NULL
,
1750 .new_connection_handler
= semihosting_service_new_connection_handler
,
1751 .input_handler
= semihosting_service_input_handler
,
1752 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1753 .keep_client_alive_handler
= NULL
,
1756 /* -------------------------------------------------------------------------
1757 * Common semihosting commands handlers. */
1759 COMMAND_HANDLER(handle_common_semihosting_command
)
1761 struct target
*target
= get_current_target(CMD_CTX
);
1764 LOG_ERROR("No target selected");
1768 struct semihosting
*semihosting
= target
->semihosting
;
1770 command_print(CMD
, "semihosting not supported for current target");
1777 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1779 if (!target_was_examined(target
)) {
1780 LOG_ERROR("Target not examined yet");
1784 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1785 LOG_ERROR("Failed to Configure semihosting");
1789 /* FIXME never let that "catch" be dropped! (???) */
1790 semihosting
->is_active
= is_active
;
1793 command_print(CMD
, "semihosting is %s",
1794 semihosting
->is_active
1795 ? "enabled" : "disabled");
1800 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1802 struct target
*target
= get_current_target(CMD_CTX
);
1805 LOG_ERROR("No target selected");
1809 struct semihosting
*semihosting
= target
->semihosting
;
1811 command_print(CMD
, "semihosting not supported for current target");
1815 if (!semihosting
->is_active
) {
1816 command_print(CMD
, "semihosting not yet enabled for current target");
1820 enum semihosting_redirect_config cfg
;
1824 return ERROR_COMMAND_SYNTAX_ERROR
;
1826 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1827 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1829 return ERROR_COMMAND_SYNTAX_ERROR
;
1830 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1831 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1832 return ERROR_COMMAND_SYNTAX_ERROR
;
1836 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1837 if (CMD_ARGC
== 3) {
1838 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1839 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1840 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1841 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1842 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1843 return ERROR_COMMAND_SYNTAX_ERROR
;
1846 return ERROR_COMMAND_SYNTAX_ERROR
;
1849 semihosting_tcp_close_cnx(semihosting
);
1850 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1852 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1853 struct semihosting_tcp_service
*service
=
1854 calloc(1, sizeof(struct semihosting_tcp_service
));
1856 LOG_ERROR("Failed to allocate semihosting TCP service.");
1860 service
->semihosting
= semihosting
;
1862 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1863 if (!service
->name
) {
1864 LOG_ERROR("Out of memory");
1869 int ret
= add_service(&semihosting_service_driver
,
1872 if (ret
!= ERROR_OK
) {
1873 LOG_ERROR("failed to initialize %s", service
->name
);
1874 free(service
->name
);
1880 semihosting
->redirect_cfg
= cfg
;
1885 COMMAND_HANDLER(handle_common_semihosting_fileio_command
)
1887 struct target
*target
= get_current_target(CMD_CTX
);
1890 LOG_ERROR("No target selected");
1894 struct semihosting
*semihosting
= target
->semihosting
;
1896 command_print(CMD
, "semihosting not supported for current target");
1900 if (!semihosting
->is_active
) {
1901 command_print(CMD
, "semihosting not yet enabled for current target");
1906 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->is_fileio
);
1908 command_print(CMD
, "semihosting fileio is %s",
1909 semihosting
->is_fileio
1910 ? "enabled" : "disabled");
1915 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1917 struct target
*target
= get_current_target(CMD_CTX
);
1921 LOG_ERROR("No target selected");
1925 struct semihosting
*semihosting
= target
->semihosting
;
1927 command_print(CMD
, "semihosting not supported for current target");
1931 free(semihosting
->cmdline
);
1932 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
1934 for (i
= 1; i
< CMD_ARGC
; i
++) {
1935 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
1938 free(semihosting
->cmdline
);
1939 semihosting
->cmdline
= cmdline
;
1942 command_print(CMD
, "semihosting command line is [%s]",
1943 semihosting
->cmdline
);
1948 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
1950 struct target
*target
= get_current_target(CMD_CTX
);
1953 LOG_ERROR("No target selected");
1957 struct semihosting
*semihosting
= target
->semihosting
;
1959 command_print(CMD
, "semihosting not supported for current target");
1963 if (!semihosting
->is_active
) {
1964 command_print(CMD
, "semihosting not yet enabled for current target");
1969 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
1971 command_print(CMD
, "semihosting resumable exit is %s",
1972 semihosting
->has_resumable_exit
1973 ? "enabled" : "disabled");
1978 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
1980 struct target
*target
= get_current_target(CMD_CTX
);
1981 struct semihosting
*semihosting
= target
->semihosting
;
1984 return ERROR_COMMAND_SYNTAX_ERROR
;
1986 if (!semihosting
->is_active
) {
1987 LOG_ERROR("semihosting not yet enabled for current target");
1991 if (!semihosting_user_op_params
) {
1992 LOG_ERROR("This command is usable only from a registered user "
1993 "semihosting event callback.");
1997 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2002 COMMAND_HANDLER(handle_common_semihosting_basedir_command
)
2004 struct target
*target
= get_current_target(CMD_CTX
);
2007 return ERROR_COMMAND_SYNTAX_ERROR
;
2010 LOG_ERROR("No target selected");
2014 struct semihosting
*semihosting
= target
->semihosting
;
2016 command_print(CMD
, "semihosting not supported for current target");
2020 if (!semihosting
->is_active
) {
2021 command_print(CMD
, "semihosting not yet enabled for current target");
2026 free(semihosting
->basedir
);
2027 semihosting
->basedir
= strdup(CMD_ARGV
[0]);
2028 if (!semihosting
->basedir
) {
2029 command_print(CMD
, "semihosting failed to allocate memory for basedir!");
2034 command_print(CMD
, "semihosting base dir: %s",
2035 semihosting
->basedir
? semihosting
->basedir
: "");
2040 const struct command_registration semihosting_common_handlers
[] = {
2042 .name
= "semihosting",
2043 .handler
= handle_common_semihosting_command
,
2044 .mode
= COMMAND_EXEC
,
2045 .usage
= "['enable'|'disable']",
2046 .help
= "activate support for semihosting operations",
2049 .name
= "semihosting_redirect",
2050 .handler
= handle_common_semihosting_redirect_command
,
2051 .mode
= COMMAND_EXEC
,
2052 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2053 .help
= "redirect semihosting IO",
2056 .name
= "semihosting_cmdline",
2057 .handler
= handle_common_semihosting_cmdline
,
2058 .mode
= COMMAND_EXEC
,
2059 .usage
= "arguments",
2060 .help
= "command line arguments to be passed to program",
2063 .name
= "semihosting_fileio",
2064 .handler
= handle_common_semihosting_fileio_command
,
2065 .mode
= COMMAND_EXEC
,
2066 .usage
= "['enable'|'disable']",
2067 .help
= "activate support for semihosting fileio operations",
2070 .name
= "semihosting_resexit",
2071 .handler
= handle_common_semihosting_resumable_exit_command
,
2072 .mode
= COMMAND_EXEC
,
2073 .usage
= "['enable'|'disable']",
2074 .help
= "activate support for semihosting resumable exit",
2077 .name
= "semihosting_read_user_param",
2078 .handler
= handle_common_semihosting_read_user_param_command
,
2079 .mode
= COMMAND_EXEC
,
2081 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2084 .name
= "semihosting_basedir",
2085 .handler
= handle_common_semihosting_basedir_command
,
2086 .mode
= COMMAND_EXEC
,
2088 .help
= "set the base directory for semihosting I/O operations",
2090 COMMAND_REGISTRATION_DONE