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)=%d", fd
, (int)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)=%d", fd
, (int)semihosting
->result
);
637 LOG_DEBUG("fstat(%d)=%d", fd
, (int)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],%d", arg
,
695 (int)semihosting
->result
);
699 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
701 * Returns the system stack and heap parameters.
704 * On entry, the PARAMETER REGISTER contains the address of a
705 * pointer to a four-field data block. The contents of the data
706 * block are filled by the function. The following C-like
707 * pseudocode describes the layout of the block:
716 * On exit, the PARAMETER REGISTER is unchanged and the data
717 * block has been updated.
719 retval
= semihosting_read_fields(target
, 1, fields
);
720 if (retval
!= ERROR_OK
)
723 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
724 /* tell the remote we have no idea */
725 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
726 retval
= target_write_memory(target
, addr
, 4,
727 semihosting
->word_size_bytes
,
729 if (retval
!= ERROR_OK
)
731 semihosting
->result
= 0;
735 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
737 * Determines whether the return code from another semihosting
738 * call is an error status or not.
740 * This call is passed a parameter block containing the error
744 * On entry, the PARAMETER REGISTER contains a pointer to a
745 * one-field data block:
746 * - field 1 The required status word to check.
749 * On exit, the RETURN REGISTER contains:
750 * - 0 if the status field is not an error indication
751 * - A nonzero value if the status field is an error indication.
753 retval
= semihosting_read_fields(target
, 1, fields
);
754 if (retval
!= ERROR_OK
)
757 uint64_t code
= semihosting_get_field(target
, 0, fields
);
758 semihosting
->result
= (code
!= 0);
761 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
763 * Checks whether a file is connected to an interactive device.
766 * On entry, the PARAMETER REGISTER contains a pointer to a
767 * one-field argument block:
768 * field 1 A handle for a previously opened file object.
771 * On exit, the RETURN REGISTER contains:
772 * - 1 if the handle identifies an interactive device.
773 * - 0 if the handle identifies a file.
774 * - A value other than 1 or 0 if an error occurs.
776 if (semihosting
->is_fileio
) {
777 semihosting
->hit_fileio
= true;
778 fileio_info
->identifier
= "isatty";
779 fileio_info
->param_1
= semihosting
->param
;
781 retval
= semihosting_read_fields(target
, 1, fields
);
782 if (retval
!= ERROR_OK
)
784 int fd
= semihosting_get_field(target
, 0, fields
);
785 semihosting
->result
= isatty(fd
);
786 semihosting
->sys_errno
= errno
;
787 LOG_DEBUG("isatty(%d)=%d", fd
, (int)semihosting
->result
);
791 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
793 * Opens a file on the host system.
795 * The file path is specified either as relative to the current
796 * directory of the host process, or absolute, using the path
797 * conventions of the host operating system.
799 * Semihosting implementations must support opening the special
800 * path name :semihosting-features as part of the semihosting
801 * extensions reporting mechanism.
803 * ARM targets interpret the special path name :tt as meaning
804 * the console input stream, for an open-read or the console
805 * output stream, for an open-write. Opening these streams is
806 * performed as part of the standard startup code for those
807 * applications that reference the C stdio streams. The
808 * semihosting extension SH_EXT_STDOUT_STDERR allows the
809 * semihosting caller to open separate output streams
810 * corresponding to stdout and stderr. This extension is
811 * reported using feature byte 0, bit 1. Use SYS_OPEN with
812 * the special path name :semihosting-features to access the
815 * If this extension is supported, the implementation must
816 * support the following additional semantics to SYS_OPEN:
817 * - If the special path name :tt is opened with an fopen
818 * mode requesting write access (w, wb, w+, or w+b), then
819 * this is a request to open stdout.
820 * - If the special path name :tt is opened with a mode
821 * requesting append access (a, ab, a+, or a+b), then this is
822 * a request to open stderr.
825 * On entry, the PARAMETER REGISTER contains a pointer to a
826 * three-field argument block:
827 * - field 1 A pointer to a null-terminated string containing
828 * a file or device name.
829 * - field 2 An integer that specifies the file opening mode.
830 * - field 3 An integer that gives the length of the string
831 * pointed to by field 1.
833 * The length does not include the terminating null character
834 * that must be present.
837 * On exit, the RETURN REGISTER contains:
838 * - A nonzero handle if the call is successful.
839 * - –1 if the call is not successful.
841 retval
= semihosting_read_fields(target
, 3, fields
);
842 if (retval
!= ERROR_OK
)
845 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
846 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
847 size_t len
= semihosting_get_field(target
, 2, fields
);
850 semihosting
->result
= -1;
851 semihosting
->sys_errno
= EINVAL
;
854 size_t basedir_len
= semihosting
->basedir
? strlen(semihosting
->basedir
) : 0;
855 uint8_t *fn
= malloc(basedir_len
+ len
+ 2);
857 semihosting
->result
= -1;
858 semihosting
->sys_errno
= ENOMEM
;
860 if (basedir_len
> 0) {
861 strcpy((char *)fn
, semihosting
->basedir
);
862 if (fn
[basedir_len
- 1] != '/')
863 fn
[basedir_len
++] = '/';
865 retval
= target_read_memory(target
, addr
, 1, len
, fn
+ basedir_len
);
866 if (retval
!= ERROR_OK
) {
870 fn
[basedir_len
+ len
] = 0;
871 /* TODO: implement the :semihosting-features special file.
873 if (semihosting
->is_fileio
) {
874 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
875 semihosting
->result
= -1;
876 semihosting
->sys_errno
= EINVAL
;
877 } else if (strcmp((char *)fn
, ":tt") == 0) {
879 semihosting
->result
= 0;
881 semihosting
->result
= 1;
883 semihosting
->result
= 2;
885 semihosting
->result
= -1;
887 semihosting
->hit_fileio
= true;
888 fileio_info
->identifier
= "open";
889 fileio_info
->param_1
= addr
;
890 fileio_info
->param_2
= len
;
891 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
892 fileio_info
->param_4
= 0644;
895 if (strcmp((char *)fn
, ":tt") == 0) {
897 * - 0-3 ("r") for stdin,
898 * - 4-7 ("w") for stdout,
899 * - 8-11 ("a") for stderr */
901 int fd
= dup(STDIN_FILENO
);
902 semihosting
->result
= fd
;
903 semihosting
->stdin_fd
= fd
;
904 semihosting
->sys_errno
= errno
;
905 LOG_DEBUG("dup(STDIN)=%d",
906 (int)semihosting
->result
);
907 } else if (mode
< 8) {
908 int fd
= dup(STDOUT_FILENO
);
909 semihosting
->result
= fd
;
910 semihosting
->stdout_fd
= fd
;
911 semihosting
->sys_errno
= errno
;
912 LOG_DEBUG("dup(STDOUT)=%d",
913 (int)semihosting
->result
);
915 int fd
= dup(STDERR_FILENO
);
916 semihosting
->result
= fd
;
917 semihosting
->stderr_fd
= fd
;
918 semihosting
->sys_errno
= errno
;
919 LOG_DEBUG("dup(STDERR)=%d",
920 (int)semihosting
->result
);
923 /* cygwin requires the permission setting
924 * otherwise it will fail to reopen a previously
926 semihosting
->result
= open((char *)fn
,
927 open_host_modeflags
[mode
],
929 semihosting
->sys_errno
= errno
;
930 LOG_DEBUG("open('%s')=%d", fn
,
931 (int)semihosting
->result
);
939 case SEMIHOSTING_SYS_READ
: /* 0x06 */
941 * Reads the contents of a file into a buffer. The file position
942 * is specified either:
943 * - Explicitly by a SYS_SEEK.
944 * - Implicitly one byte beyond the previous SYS_READ or
947 * The file position is at the start of the file when it is
948 * opened, and is lost when the file is closed. Perform the
949 * file operation as a single action whenever possible. For
950 * example, do not split a read of 16KB into four 4KB chunks
951 * unless there is no alternative.
954 * On entry, the PARAMETER REGISTER contains a pointer to a
955 * three-field data block:
956 * - field 1 Contains a handle for a file previously opened
958 * - field 2 Points to a buffer.
959 * - field 3 Contains the number of bytes to read to the buffer
963 * On exit, the RETURN REGISTER contains the number of bytes not
964 * filled in the buffer (buffer_length - bytes_read) as follows:
965 * - If the RETURN REGISTER is 0, the entire buffer was
966 * successfully filled.
967 * - If the RETURN REGISTER is the same as field 3, no bytes
968 * were read (EOF can be assumed).
969 * - If the RETURN REGISTER contains a value smaller than
970 * field 3, the read succeeded but the buffer was only partly
971 * filled. For interactive devices, this is the most common
974 retval
= semihosting_read_fields(target
, 3, fields
);
975 if (retval
!= ERROR_OK
)
978 int fd
= semihosting_get_field(target
, 0, fields
);
979 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
980 size_t len
= semihosting_get_field(target
, 2, fields
);
981 if (semihosting
->is_fileio
) {
982 semihosting
->hit_fileio
= true;
983 fileio_info
->identifier
= "read";
984 fileio_info
->param_1
= fd
;
985 fileio_info
->param_2
= addr
;
986 fileio_info
->param_3
= len
;
988 uint8_t *buf
= malloc(len
);
990 semihosting
->result
= -1;
991 semihosting
->sys_errno
= ENOMEM
;
993 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
994 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%d",
998 (int)semihosting
->result
);
999 if (semihosting
->result
>= 0) {
1000 retval
= target_write_buffer(target
, addr
,
1001 semihosting
->result
,
1003 if (retval
!= ERROR_OK
) {
1007 /* the number of bytes NOT filled in */
1008 semihosting
->result
= len
-
1009 semihosting
->result
;
1017 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1019 * Reads a byte from the console.
1022 * The PARAMETER REGISTER must contain 0. There are no other
1023 * parameters or values possible.
1026 * On exit, the RETURN REGISTER contains the byte read from
1029 if (semihosting
->is_fileio
) {
1030 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1033 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1034 LOG_DEBUG("getchar()=%d", (int)semihosting
->result
);
1037 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1039 * Deletes a specified file on the host filing system.
1042 * On entry, the PARAMETER REGISTER contains a pointer to a
1043 * two-field argument block:
1044 * - field 1 Points to a null-terminated string that gives the
1045 * path name of the file to be deleted.
1046 * - field 2 The length of the string.
1049 * On exit, the RETURN REGISTER contains:
1050 * - 0 if the delete is successful
1051 * - A nonzero, host-specific error code if the delete fails.
1053 retval
= semihosting_read_fields(target
, 2, fields
);
1054 if (retval
!= ERROR_OK
)
1057 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1058 size_t len
= semihosting_get_field(target
, 1, fields
);
1059 if (semihosting
->is_fileio
) {
1060 semihosting
->hit_fileio
= true;
1061 fileio_info
->identifier
= "unlink";
1062 fileio_info
->param_1
= addr
;
1063 fileio_info
->param_2
= len
;
1065 uint8_t *fn
= malloc(len
+1);
1067 semihosting
->result
= -1;
1068 semihosting
->sys_errno
= ENOMEM
;
1071 target_read_memory(target
, addr
, 1, len
,
1073 if (retval
!= ERROR_OK
) {
1078 semihosting
->result
= remove((char *)fn
);
1079 semihosting
->sys_errno
= errno
;
1080 LOG_DEBUG("remove('%s')=%d", fn
,
1081 (int)semihosting
->result
);
1089 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1091 * Renames a specified file.
1094 * On entry, the PARAMETER REGISTER contains a pointer to a
1095 * four-field data block:
1096 * - field 1 A pointer to the name of the old file.
1097 * - field 2 The length of the old filename.
1098 * - field 3 A pointer to the new filename.
1099 * - field 4 The length of the new filename. Both strings are
1103 * On exit, the RETURN REGISTER contains:
1104 * - 0 if the rename is successful.
1105 * - A nonzero, host-specific error code if the rename fails.
1107 retval
= semihosting_read_fields(target
, 4, fields
);
1108 if (retval
!= ERROR_OK
)
1111 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1112 size_t len1
= semihosting_get_field(target
, 1, fields
);
1113 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1114 size_t len2
= semihosting_get_field(target
, 3, fields
);
1115 if (semihosting
->is_fileio
) {
1116 semihosting
->hit_fileio
= true;
1117 fileio_info
->identifier
= "rename";
1118 fileio_info
->param_1
= addr1
;
1119 fileio_info
->param_2
= len1
;
1120 fileio_info
->param_3
= addr2
;
1121 fileio_info
->param_4
= len2
;
1123 uint8_t *fn1
= malloc(len1
+1);
1124 uint8_t *fn2
= malloc(len2
+1);
1128 semihosting
->result
= -1;
1129 semihosting
->sys_errno
= ENOMEM
;
1131 retval
= target_read_memory(target
, addr1
, 1, len1
,
1133 if (retval
!= ERROR_OK
) {
1138 retval
= target_read_memory(target
, addr2
, 1, len2
,
1140 if (retval
!= ERROR_OK
) {
1147 semihosting
->result
= rename((char *)fn1
,
1149 semihosting
->sys_errno
= errno
;
1150 LOG_DEBUG("rename('%s', '%s')=%d", fn1
, fn2
,
1151 (int)semihosting
->result
);
1160 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1162 * Seeks to a specified position in a file using an offset
1163 * specified from the start of the file. The file is assumed
1164 * to be a byte array and the offset is given in bytes.
1167 * On entry, the PARAMETER REGISTER contains a pointer to a
1168 * two-field data block:
1169 * - field 1 A handle for a seekable file object.
1170 * - field 2 The absolute byte position to seek to.
1173 * On exit, the RETURN REGISTER contains:
1174 * - 0 if the request is successful.
1175 * - A negative value if the request is not successful.
1176 * Use SYS_ERRNO to read the value of the host errno variable
1177 * describing the error.
1179 * Note: The effect of seeking outside the current extent of
1180 * the file object is undefined.
1182 retval
= semihosting_read_fields(target
, 2, fields
);
1183 if (retval
!= ERROR_OK
)
1186 int fd
= semihosting_get_field(target
, 0, fields
);
1187 off_t pos
= semihosting_get_field(target
, 1, fields
);
1188 if (semihosting
->is_fileio
) {
1189 semihosting
->hit_fileio
= true;
1190 fileio_info
->identifier
= "lseek";
1191 fileio_info
->param_1
= fd
;
1192 fileio_info
->param_2
= pos
;
1193 fileio_info
->param_3
= SEEK_SET
;
1195 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1196 semihosting
->sys_errno
= errno
;
1197 LOG_DEBUG("lseek(%d, %d)=%d", fd
, (int)pos
,
1198 (int)semihosting
->result
);
1199 if (semihosting
->result
== pos
)
1200 semihosting
->result
= 0;
1205 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1207 * Passes a command to the host command-line interpreter.
1208 * This enables you to execute a system command such as dir,
1209 * ls, or pwd. The terminal I/O is on the host, and is not
1210 * visible to the target.
1213 * On entry, the PARAMETER REGISTER contains a pointer to a
1214 * two-field argument block:
1215 * - field 1 Points to a string to be passed to the host
1216 * command-line interpreter.
1217 * - field 2 The length of the string.
1220 * On exit, the RETURN REGISTER contains the return status.
1223 /* Provide SYS_SYSTEM functionality. Uses the
1224 * libc system command, there may be a reason *NOT*
1225 * to use this, but as I can't think of one, I
1226 * implemented it this way.
1228 retval
= semihosting_read_fields(target
, 2, fields
);
1229 if (retval
!= ERROR_OK
)
1232 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1233 size_t len
= semihosting_get_field(target
, 1, fields
);
1234 if (semihosting
->is_fileio
) {
1235 semihosting
->hit_fileio
= true;
1236 fileio_info
->identifier
= "system";
1237 fileio_info
->param_1
= addr
;
1238 fileio_info
->param_2
= len
;
1240 uint8_t *cmd
= malloc(len
+1);
1242 semihosting
->result
= -1;
1243 semihosting
->sys_errno
= ENOMEM
;
1245 retval
= target_read_memory(target
,
1250 if (retval
!= ERROR_OK
) {
1255 semihosting
->result
= system(
1257 LOG_DEBUG("system('%s')=%d",
1259 (int)semihosting
->result
);
1268 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1270 * Returns the number of seconds since 00:00 January 1, 1970.
1271 * This value is real-world time, regardless of any debug agent
1275 * There are no parameters.
1278 * On exit, the RETURN REGISTER contains the number of seconds.
1280 semihosting
->result
= time(NULL
);
1283 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1285 * Writes the contents of a buffer to a specified file at the
1286 * current file position. The file position is specified either:
1287 * - Explicitly, by a SYS_SEEK.
1288 * - Implicitly as one byte beyond the previous SYS_READ or
1289 * SYS_WRITE request.
1291 * The file position is at the start of the file when the file
1292 * is opened, and is lost when the file is closed.
1294 * Perform the file operation as a single action whenever
1295 * possible. For example, do not split a write of 16KB into
1296 * four 4KB chunks unless there is no alternative.
1299 * On entry, the PARAMETER REGISTER contains a pointer to a
1300 * three-field data block:
1301 * - field 1 Contains a handle for a file previously opened
1303 * - field 2 Points to the memory containing the data to be written.
1304 * - field 3 Contains the number of bytes to be written from
1305 * the buffer to the file.
1308 * On exit, the RETURN REGISTER contains:
1309 * - 0 if the call is successful.
1310 * - The number of bytes that are not written, if there is an error.
1312 retval
= semihosting_read_fields(target
, 3, fields
);
1313 if (retval
!= ERROR_OK
)
1316 int fd
= semihosting_get_field(target
, 0, fields
);
1317 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1318 size_t len
= semihosting_get_field(target
, 2, fields
);
1319 if (semihosting
->is_fileio
) {
1320 semihosting
->hit_fileio
= true;
1321 fileio_info
->identifier
= "write";
1322 fileio_info
->param_1
= fd
;
1323 fileio_info
->param_2
= addr
;
1324 fileio_info
->param_3
= len
;
1326 uint8_t *buf
= malloc(len
);
1328 semihosting
->result
= -1;
1329 semihosting
->sys_errno
= ENOMEM
;
1331 retval
= target_read_buffer(target
, addr
, len
, buf
);
1332 if (retval
!= ERROR_OK
) {
1336 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1337 semihosting
->sys_errno
= errno
;
1338 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%d",
1342 (int)semihosting
->result
);
1343 if (semihosting
->result
>= 0) {
1344 /* The number of bytes that are NOT written.
1346 semihosting
->result
= len
-
1347 semihosting
->result
;
1356 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1358 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1359 * to the debug channel. When executed under a semihosting
1360 * debugger, the character appears on the host debugger console.
1363 * On entry, the PARAMETER REGISTER contains a pointer to the
1367 * None. The RETURN REGISTER is corrupted.
1369 if (semihosting
->is_fileio
) {
1370 semihosting
->hit_fileio
= true;
1371 fileio_info
->identifier
= "write";
1372 fileio_info
->param_1
= 1;
1373 fileio_info
->param_2
= semihosting
->param
;
1374 fileio_info
->param_3
= 1;
1376 uint64_t addr
= semihosting
->param
;
1378 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1379 if (retval
!= ERROR_OK
)
1381 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1382 semihosting
->result
= 0;
1386 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1388 * Writes a null-terminated string to the debug channel.
1389 * When executed under a semihosting debugger, the characters
1390 * appear on the host debugger console.
1393 * On entry, the PARAMETER REGISTER contains a pointer to the
1394 * first byte of the string.
1397 * None. The RETURN REGISTER is corrupted.
1399 if (semihosting
->is_fileio
) {
1401 uint64_t addr
= semihosting
->param
;
1404 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1405 if (retval
!= ERROR_OK
)
1411 semihosting
->hit_fileio
= true;
1412 fileio_info
->identifier
= "write";
1413 fileio_info
->param_1
= 1;
1414 fileio_info
->param_2
= semihosting
->param
;
1415 fileio_info
->param_3
= count
;
1417 uint64_t addr
= semihosting
->param
;
1420 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1421 if (retval
!= ERROR_OK
)
1425 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1427 semihosting
->result
= 0;
1431 case SEMIHOSTING_USER_CMD_0x100
... SEMIHOSTING_USER_CMD_0x107
:
1433 * This is a user defined operation (while user cmds 0x100-0x1ff
1434 * are possible, only 0x100-0x107 are currently implemented).
1436 * Reads the user operation parameters from target, then fires the
1437 * corresponding target event. When the target callbacks returned,
1438 * cleans up the command parameter buffer.
1441 * On entry, the PARAMETER REGISTER contains a pointer to a
1442 * two-field data block:
1443 * - field 1 Contains a pointer to the bound command parameter
1445 * - field 2 Contains the command parameter string length
1448 * On exit, the RETURN REGISTER contains the return status.
1450 if (semihosting
->user_command_extension
) {
1451 retval
= semihosting
->user_command_extension(target
);
1452 if (retval
!= ERROR_NOT_IMPLEMENTED
)
1454 /* If custom user command not handled, we are looking for the TCL handler */
1457 assert(!semihosting_user_op_params
);
1458 retval
= semihosting_read_fields(target
, 2, fields
);
1459 if (retval
!= ERROR_OK
) {
1460 LOG_ERROR("Failed to read fields for user defined command"
1461 " op=0x%x", semihosting
->op
);
1465 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1467 size_t len
= semihosting_get_field(target
, 1, fields
);
1468 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1469 LOG_ERROR("The maximum length for user defined command "
1470 "parameter is %u, received length is %zu (op=0x%x)",
1471 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1477 semihosting_user_op_params
= malloc(len
+ 1);
1478 if (!semihosting_user_op_params
)
1480 semihosting_user_op_params
[len
] = 0;
1482 retval
= target_read_buffer(target
, addr
, len
,
1483 (uint8_t *)(semihosting_user_op_params
));
1484 if (retval
!= ERROR_OK
) {
1485 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1487 free(semihosting_user_op_params
);
1488 semihosting_user_op_params
= NULL
;
1492 target_handle_event(target
, semihosting
->op
);
1493 free(semihosting_user_op_params
);
1494 semihosting_user_op_params
= NULL
;
1495 semihosting
->result
= 0;
1498 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1500 * Returns the number of elapsed target ticks since execution
1502 * Use SYS_TICKFREQ to determine the tick frequency.
1505 * On entry, the PARAMETER REGISTER points to a two-field data
1506 * block to be used for returning the number of elapsed ticks:
1507 * - field 1 The least significant field and is at the low address.
1508 * - field 2 The most significant field and is at the high address.
1511 * On entry the PARAMETER REGISTER points to a one-field data
1512 * block to be used for returning the number of elapsed ticks:
1513 * - field 1 The number of elapsed ticks as a 64-bit value.
1517 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1518 * REGISTER is unchanged, and the data block pointed to by the
1519 * PARAMETER REGISTER is filled in with the number of elapsed
1521 * - On failure, the RETURN REGISTER contains -1, and the
1522 * PARAMETER REGISTER contains -1.
1524 * Note: Some semihosting implementations might not support this
1525 * semihosting operation, and they always return -1 in the
1529 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1531 * Returns the tick frequency.
1534 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1537 * On exit, the RETURN REGISTER contains either:
1538 * - The number of ticks per second.
1539 * - –1 if the target does not know the value of one tick.
1541 * Note: Some semihosting implementations might not support
1542 * this semihosting operation, and they always return -1 in the
1546 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1548 * Returns a temporary name for a file identified by a system
1552 * On entry, the PARAMETER REGISTER contains a pointer to a
1553 * three-word argument block:
1554 * - field 1 A pointer to a buffer.
1555 * - field 2 A target identifier for this filename. Its value
1556 * must be an integer in the range 0-255.
1557 * - field 3 Contains the length of the buffer. The length must
1558 * be at least the value of L_tmpnam on the host system.
1561 * On exit, the RETURN REGISTER contains:
1562 * - 0 if the call is successful.
1563 * - –1 if an error occurs.
1565 * The buffer pointed to by the PARAMETER REGISTER contains
1566 * the filename, prefixed with a suitable directory name.
1567 * If you use the same target identifier again, the same
1568 * filename is returned.
1570 * Note: The returned string must be null-terminated.
1574 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1575 (unsigned) semihosting
->op
);
1576 semihosting
->result
= -1;
1577 semihosting
->sys_errno
= ENOTSUP
;
1580 if (!semihosting
->hit_fileio
) {
1581 retval
= semihosting
->post_result(target
);
1582 if (retval
!= ERROR_OK
) {
1583 LOG_ERROR("Failed to post semihosting result");
1591 /* -------------------------------------------------------------------------
1592 * Local functions. */
1594 static int semihosting_common_fileio_info(struct target
*target
,
1595 struct gdb_fileio_info
*fileio_info
)
1597 struct semihosting
*semihosting
= target
->semihosting
;
1602 * To avoid unnecessary duplication, semihosting prepares the
1603 * fileio_info structure out-of-band when the target halts. See
1604 * do_semihosting for more detail.
1606 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1612 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1613 int fileio_errno
, bool ctrl_c
)
1615 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1616 struct semihosting
*semihosting
= target
->semihosting
;
1620 /* clear pending status */
1621 semihosting
->hit_fileio
= false;
1623 semihosting
->result
= result
;
1624 semihosting
->sys_errno
= fileio_errno
;
1627 * Some fileio results do not match up with what the semihosting
1628 * operation expects; for these operations, we munge the results
1631 switch (semihosting
->op
) {
1632 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1633 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1635 semihosting
->result
= fileio_info
->param_3
; /* Zero bytes read/written. */
1637 semihosting
->result
= (int64_t)fileio_info
->param_3
- result
;
1640 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1642 semihosting
->result
= 0;
1646 return semihosting
->post_result(target
);
1649 /* -------------------------------------------------------------------------
1650 * Utility functions. */
1653 * Read all fields of a command from target to buffer.
1655 int semihosting_read_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_read_memory(target
, semihosting
->param
, 4,
1661 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1665 * Write all fields of a command from buffer to target.
1667 int semihosting_write_fields(struct target
*target
, size_t number
,
1670 struct semihosting
*semihosting
= target
->semihosting
;
1671 /* Use 4-byte multiples to trigger fast memory access. */
1672 return target_write_memory(target
, semihosting
->param
, 4,
1673 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1677 * Extract a field from the buffer, considering register size and endianness.
1679 uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1682 struct semihosting
*semihosting
= target
->semihosting
;
1683 if (semihosting
->word_size_bytes
== 8)
1684 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1686 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1690 * Store a field in the buffer, considering register size and endianness.
1692 void semihosting_set_field(struct target
*target
, uint64_t value
,
1696 struct semihosting
*semihosting
= target
->semihosting
;
1697 if (semihosting
->word_size_bytes
== 8)
1698 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1700 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1703 /* -------------------------------------------------------------------------
1704 * Semihosting redirect over TCP structs and functions */
1706 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1708 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1709 service
->semihosting
->tcp_connection
= connection
;
1714 static int semihosting_service_input_handler(struct connection
*connection
)
1716 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1718 if (!connection
->input_pending
) {
1719 /* consume received data, not for semihosting IO */
1720 const int buf_len
= 100;
1722 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1724 if (bytes_read
== 0) {
1725 return ERROR_SERVER_REMOTE_CLOSED
;
1726 } else if (bytes_read
== -1) {
1727 LOG_ERROR("error during read: %s", strerror(errno
));
1728 return ERROR_SERVER_REMOTE_CLOSED
;
1730 } else if (service
->error
!= ERROR_OK
) {
1731 return ERROR_SERVER_REMOTE_CLOSED
;
1737 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1739 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1741 free(service
->name
);
1748 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1750 if (!semihosting
->tcp_connection
)
1753 struct service
*service
= semihosting
->tcp_connection
->service
;
1754 remove_service(service
->name
, service
->port
);
1755 semihosting
->tcp_connection
= NULL
;
1759 static const struct service_driver semihosting_service_driver
= {
1760 .name
= "semihosting",
1761 .new_connection_during_keep_alive_handler
= NULL
,
1762 .new_connection_handler
= semihosting_service_new_connection_handler
,
1763 .input_handler
= semihosting_service_input_handler
,
1764 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1765 .keep_client_alive_handler
= NULL
,
1768 /* -------------------------------------------------------------------------
1769 * Common semihosting commands handlers. */
1771 COMMAND_HANDLER(handle_common_semihosting_command
)
1773 struct target
*target
= get_current_target(CMD_CTX
);
1776 LOG_ERROR("No target selected");
1780 struct semihosting
*semihosting
= target
->semihosting
;
1782 command_print(CMD
, "semihosting not supported for current target");
1789 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1791 if (!target_was_examined(target
)) {
1792 LOG_ERROR("Target not examined yet");
1796 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1797 LOG_ERROR("Failed to Configure semihosting");
1801 /* FIXME never let that "catch" be dropped! (???) */
1802 semihosting
->is_active
= is_active
;
1805 command_print(CMD
, "semihosting is %s",
1806 semihosting
->is_active
1807 ? "enabled" : "disabled");
1812 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1814 struct target
*target
= get_current_target(CMD_CTX
);
1817 LOG_ERROR("No target selected");
1821 struct semihosting
*semihosting
= target
->semihosting
;
1823 command_print(CMD
, "semihosting not supported for current target");
1827 if (!semihosting
->is_active
) {
1828 command_print(CMD
, "semihosting not yet enabled for current target");
1832 enum semihosting_redirect_config cfg
;
1836 return ERROR_COMMAND_SYNTAX_ERROR
;
1838 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1839 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1841 return ERROR_COMMAND_SYNTAX_ERROR
;
1842 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1843 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1844 return ERROR_COMMAND_SYNTAX_ERROR
;
1848 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1849 if (CMD_ARGC
== 3) {
1850 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1851 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1852 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1853 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1854 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1855 return ERROR_COMMAND_SYNTAX_ERROR
;
1858 return ERROR_COMMAND_SYNTAX_ERROR
;
1861 semihosting_tcp_close_cnx(semihosting
);
1862 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1864 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1865 struct semihosting_tcp_service
*service
=
1866 calloc(1, sizeof(struct semihosting_tcp_service
));
1868 LOG_ERROR("Failed to allocate semihosting TCP service.");
1872 service
->semihosting
= semihosting
;
1874 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1875 if (!service
->name
) {
1876 LOG_ERROR("Out of memory");
1881 int ret
= add_service(&semihosting_service_driver
,
1884 if (ret
!= ERROR_OK
) {
1885 LOG_ERROR("failed to initialize %s", service
->name
);
1886 free(service
->name
);
1892 semihosting
->redirect_cfg
= cfg
;
1897 COMMAND_HANDLER(handle_common_semihosting_fileio_command
)
1899 struct target
*target
= get_current_target(CMD_CTX
);
1902 LOG_ERROR("No target selected");
1906 struct semihosting
*semihosting
= target
->semihosting
;
1908 command_print(CMD
, "semihosting not supported for current target");
1912 if (!semihosting
->is_active
) {
1913 command_print(CMD
, "semihosting not yet enabled for current target");
1918 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->is_fileio
);
1920 command_print(CMD
, "semihosting fileio is %s",
1921 semihosting
->is_fileio
1922 ? "enabled" : "disabled");
1927 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1929 struct target
*target
= get_current_target(CMD_CTX
);
1933 LOG_ERROR("No target selected");
1937 struct semihosting
*semihosting
= target
->semihosting
;
1939 command_print(CMD
, "semihosting not supported for current target");
1943 free(semihosting
->cmdline
);
1944 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
1946 for (i
= 1; i
< CMD_ARGC
; i
++) {
1947 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
1950 free(semihosting
->cmdline
);
1951 semihosting
->cmdline
= cmdline
;
1954 command_print(CMD
, "semihosting command line is [%s]",
1955 semihosting
->cmdline
);
1960 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
1962 struct target
*target
= get_current_target(CMD_CTX
);
1965 LOG_ERROR("No target selected");
1969 struct semihosting
*semihosting
= target
->semihosting
;
1971 command_print(CMD
, "semihosting not supported for current target");
1975 if (!semihosting
->is_active
) {
1976 command_print(CMD
, "semihosting not yet enabled for current target");
1981 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
1983 command_print(CMD
, "semihosting resumable exit is %s",
1984 semihosting
->has_resumable_exit
1985 ? "enabled" : "disabled");
1990 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
1992 struct target
*target
= get_current_target(CMD_CTX
);
1993 struct semihosting
*semihosting
= target
->semihosting
;
1996 return ERROR_COMMAND_SYNTAX_ERROR
;
1998 if (!semihosting
->is_active
) {
1999 LOG_ERROR("semihosting not yet enabled for current target");
2003 if (!semihosting_user_op_params
) {
2004 LOG_ERROR("This command is usable only from a registered user "
2005 "semihosting event callback.");
2009 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2014 COMMAND_HANDLER(handle_common_semihosting_basedir_command
)
2016 struct target
*target
= get_current_target(CMD_CTX
);
2019 return ERROR_COMMAND_SYNTAX_ERROR
;
2022 LOG_ERROR("No target selected");
2026 struct semihosting
*semihosting
= target
->semihosting
;
2028 command_print(CMD
, "semihosting not supported for current target");
2032 if (!semihosting
->is_active
) {
2033 command_print(CMD
, "semihosting not yet enabled for current target");
2038 free(semihosting
->basedir
);
2039 semihosting
->basedir
= strdup(CMD_ARGV
[0]);
2040 if (!semihosting
->basedir
) {
2041 command_print(CMD
, "semihosting failed to allocate memory for basedir!");
2046 command_print(CMD
, "semihosting base dir: %s",
2047 semihosting
->basedir
? semihosting
->basedir
: "");
2052 const struct command_registration semihosting_common_handlers
[] = {
2054 .name
= "semihosting",
2055 .handler
= handle_common_semihosting_command
,
2056 .mode
= COMMAND_EXEC
,
2057 .usage
= "['enable'|'disable']",
2058 .help
= "activate support for semihosting operations",
2061 .name
= "semihosting_redirect",
2062 .handler
= handle_common_semihosting_redirect_command
,
2063 .mode
= COMMAND_EXEC
,
2064 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2065 .help
= "redirect semihosting IO",
2068 .name
= "semihosting_cmdline",
2069 .handler
= handle_common_semihosting_cmdline
,
2070 .mode
= COMMAND_EXEC
,
2071 .usage
= "arguments",
2072 .help
= "command line arguments to be passed to program",
2075 .name
= "semihosting_fileio",
2076 .handler
= handle_common_semihosting_fileio_command
,
2077 .mode
= COMMAND_EXEC
,
2078 .usage
= "['enable'|'disable']",
2079 .help
= "activate support for semihosting fileio operations",
2082 .name
= "semihosting_resexit",
2083 .handler
= handle_common_semihosting_resumable_exit_command
,
2084 .mode
= COMMAND_EXEC
,
2085 .usage
= "['enable'|'disable']",
2086 .help
= "activate support for semihosting resumable exit",
2089 .name
= "semihosting_read_user_param",
2090 .handler
= handle_common_semihosting_read_user_param_command
,
2091 .mode
= COMMAND_EXEC
,
2093 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2096 .name
= "semihosting_basedir",
2097 .handler
= handle_common_semihosting_basedir_command
,
2098 .mode
= COMMAND_EXEC
,
2100 .help
= "set the base directory for semihosting I/O operations",
2102 COMMAND_REGISTRATION_DONE