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 int result
= write(fd
, buf
, size
);
228 semihosting
->sys_errno
= errno
;
232 static ssize_t
semihosting_redirect_read(struct semihosting
*semihosting
, void *buf
, int size
)
234 if (!semihosting
->tcp_connection
) {
235 LOG_ERROR("No connected TCP client for semihosting");
236 semihosting
->sys_errno
= EBADF
; /* Bad file number */
240 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
242 service
->error
= ERROR_OK
;
243 semihosting
->tcp_connection
->input_pending
= true;
245 int retval
= connection_read(semihosting
->tcp_connection
, buf
, size
);
248 service
->error
= ERROR_SERVER_REMOTE_CLOSED
;
251 log_socket_error(service
->name
);
253 semihosting
->tcp_connection
->input_pending
= false;
258 static inline int semihosting_putchar(struct semihosting
*semihosting
, int fd
, int c
)
260 if (semihosting_is_redirected(semihosting
, fd
))
261 return semihosting_redirect_write(semihosting
, &c
, 1);
263 /* default putchar */
267 static inline ssize_t
semihosting_read(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
269 if (semihosting_is_redirected(semihosting
, fd
))
270 return semihosting_redirect_read(semihosting
, buf
, size
);
273 ssize_t result
= read(fd
, buf
, size
);
275 semihosting
->sys_errno
= errno
;
280 static inline int semihosting_getchar(struct semihosting
*semihosting
, int fd
)
282 if (semihosting_is_redirected(semihosting
, fd
)) {
285 if (semihosting_redirect_read(semihosting
, &c
, 1) > 0)
291 /* default getchar */
296 * User operation parameter string storage buffer. Contains valid data when the
297 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
299 static char *semihosting_user_op_params
;
301 const char *semihosting_opcode_to_str(const uint64_t opcode
)
304 case SEMIHOSTING_SYS_CLOSE
:
306 case SEMIHOSTING_SYS_CLOCK
:
308 case SEMIHOSTING_SYS_ELAPSED
:
310 case SEMIHOSTING_SYS_ERRNO
:
312 case SEMIHOSTING_SYS_EXIT
:
314 case SEMIHOSTING_SYS_EXIT_EXTENDED
:
315 return "EXIT_EXTENDED";
316 case SEMIHOSTING_SYS_FLEN
:
318 case SEMIHOSTING_SYS_GET_CMDLINE
:
319 return "GET_CMDLINE";
320 case SEMIHOSTING_SYS_HEAPINFO
:
322 case SEMIHOSTING_SYS_ISERROR
:
324 case SEMIHOSTING_SYS_ISTTY
:
326 case SEMIHOSTING_SYS_OPEN
:
328 case SEMIHOSTING_SYS_READ
:
330 case SEMIHOSTING_SYS_READC
:
332 case SEMIHOSTING_SYS_REMOVE
:
334 case SEMIHOSTING_SYS_RENAME
:
336 case SEMIHOSTING_SYS_SEEK
:
338 case SEMIHOSTING_SYS_SYSTEM
:
340 case SEMIHOSTING_SYS_TICKFREQ
:
342 case SEMIHOSTING_SYS_TIME
:
344 case SEMIHOSTING_SYS_TMPNAM
:
346 case SEMIHOSTING_SYS_WRITE
:
348 case SEMIHOSTING_SYS_WRITEC
:
350 case SEMIHOSTING_SYS_WRITE0
:
352 case SEMIHOSTING_USER_CMD_0X100
... SEMIHOSTING_USER_CMD_0X1FF
:
354 case SEMIHOSTING_ARM_RESERVED_START
... SEMIHOSTING_ARM_RESERVED_END
:
355 return "ARM_RESERVED_CMD";
362 * Portable implementation of ARM semihosting calls.
363 * Performs the currently pending semihosting operation
364 * encoded in target->semihosting.
366 int semihosting_common(struct target
*target
)
368 struct semihosting
*semihosting
= target
->semihosting
;
370 /* Silently ignore if the semihosting field was not set. */
374 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
377 * By default return an error.
378 * The actual result must be set by each function
380 semihosting
->result
= -1;
382 /* Most operations are resumable, except the two exit calls. */
383 semihosting
->is_resumable
= true;
387 /* Enough space to hold 4 long words. */
390 LOG_DEBUG("op=0x%x (%s), param=0x%" PRIx64
, semihosting
->op
,
391 semihosting_opcode_to_str(semihosting
->op
),
394 switch (semihosting
->op
) {
396 case SEMIHOSTING_SYS_CLOCK
: /* 0x10 */
398 * Returns the number of centiseconds (hundredths of a second)
399 * since the execution started.
401 * Values returned can be of limited use for some benchmarking
402 * purposes because of communication overhead or other
403 * agent-specific factors. For example, with a debug hardware
404 * unit the request is passed back to the host for execution.
405 * This can lead to unpredictable delays in transmission and
406 * process scheduling.
408 * Use this function to calculate time intervals, by calculating
409 * differences between intervals with and without the code
410 * sequence to be timed.
413 * The PARAMETER REGISTER must contain 0. There are no other
417 * On exit, the RETURN REGISTER contains:
418 * - The number of centiseconds since some arbitrary start
419 * point, if the call is successful.
420 * - –1 if the call is not successful. For example, because
421 * of a communications error.
424 clock_t delta
= clock() - semihosting
->setup_time
;
426 semihosting
->result
= delta
/ (CLOCKS_PER_SEC
/ 100);
430 case SEMIHOSTING_SYS_CLOSE
: /* 0x02 */
432 * Closes a file on the host system. The handle must reference
433 * a file that was opened with SYS_OPEN.
436 * On entry, the PARAMETER REGISTER contains a pointer to a
437 * one-field argument block:
438 * - field 1 Contains a handle for an open file.
441 * On exit, the RETURN REGISTER contains:
442 * - 0 if the call is successful
443 * - –1 if the call is not successful.
445 retval
= semihosting_read_fields(target
, 1, fields
);
446 if (retval
!= ERROR_OK
)
449 int fd
= semihosting_get_field(target
, 0, fields
);
450 /* Do not allow to close OpenOCD's own standard streams */
451 if (fd
== 0 || fd
== 1 || fd
== 2) {
452 LOG_DEBUG("ignoring semihosting attempt to close %s",
453 (fd
== 0) ? "stdin" :
454 (fd
== 1) ? "stdout" : "stderr");
455 /* Just pretend success */
456 semihosting
->result
= 0;
459 /* Close the descriptor */
460 if (semihosting
->is_fileio
) {
461 semihosting
->hit_fileio
= true;
462 fileio_info
->identifier
= "close";
463 fileio_info
->param_1
= fd
;
465 semihosting
->result
= close(fd
);
466 if (semihosting
->result
== -1)
467 semihosting
->sys_errno
= errno
;
468 LOG_DEBUG("close(%d)=%" PRId64
, fd
, semihosting
->result
);
473 case SEMIHOSTING_SYS_ERRNO
: /* 0x13 */
475 * Returns the value of the C library errno variable that is
476 * associated with the semihosting implementation. The errno
477 * variable can be set by a number of C library semihosted
478 * functions, including:
486 * Whether errno is set or not, and to what value, is entirely
487 * host-specific, except where the ISO C standard defines the
491 * There are no parameters. The PARAMETER REGISTER must be 0.
494 * On exit, the RETURN REGISTER contains the value of the C
495 * library errno variable.
497 semihosting
->result
= semihosting
->sys_errno
;
500 case SEMIHOSTING_SYS_EXIT
: /* 0x18 */
502 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
503 * previous versions of the documentation.
505 * An application calls this operation to report an exception
506 * to the debugger directly. The most common use is to report
507 * that execution has completed, using ADP_Stopped_ApplicationExit.
509 * Note: This semihosting operation provides no means for 32-bit
510 * callers to indicate an application exit with a specified exit
511 * code. Semihosting callers may prefer to check for the presence
512 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
513 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
517 * On entry, the PARAMETER register is set to a reason code
518 * describing the cause of the trap. Not all semihosting client
519 * implementations will necessarily trap every corresponding
520 * event. Important reason codes are:
522 * - ADP_Stopped_ApplicationExit 0x20026
523 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
526 * On entry, the PARAMETER REGISTER contains a pointer to a
527 * two-field argument block:
528 * - field 1 The exception type, which is one of the set of
529 * reason codes in the above tables.
530 * - field 2 A subcode, whose meaning depends on the reason
532 * In particular, if field 1 is ADP_Stopped_ApplicationExit
533 * then field 2 is an exit status code, as passed to the C
534 * standard library exit() function. A simulator receiving
535 * this request must notify a connected debugger, if present,
536 * and then exit with the specified status.
539 * No return is expected from these calls. However, it is
540 * possible for the debugger to request that the application
541 * continues by performing an RDI_Execute request or equivalent.
542 * In this case, execution continues with the registers as they
543 * were on entry to the operation, or as subsequently modified
546 if (semihosting
->word_size_bytes
== 8) {
547 retval
= semihosting_read_fields(target
, 2, fields
);
548 if (retval
!= ERROR_OK
)
551 int type
= semihosting_get_field(target
, 0, fields
);
552 int code
= semihosting_get_field(target
, 1, fields
);
554 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
555 if (!gdb_get_actual_connections())
559 "semihosting: *** application exited with %d ***\n",
564 "semihosting: application exception %#x\n",
569 if (semihosting
->param
== ADP_STOPPED_APPLICATION_EXIT
) {
570 if (!gdb_get_actual_connections())
574 "semihosting: *** application exited normally ***\n");
576 } else if (semihosting
->param
== ADP_STOPPED_RUN_TIME_ERROR
) {
577 /* Chosen more or less arbitrarily to have a nicer message,
578 * otherwise all other return the same exit code 1. */
579 if (!gdb_get_actual_connections())
583 "semihosting: *** application exited with error ***\n");
586 if (!gdb_get_actual_connections())
590 "semihosting: application exception %#x\n",
591 (unsigned) semihosting
->param
);
595 if (!semihosting
->has_resumable_exit
) {
596 semihosting
->is_resumable
= false;
597 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
601 case SEMIHOSTING_SYS_EXIT_EXTENDED
: /* 0x20 */
603 * This operation is only supported if the semihosting extension
604 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
605 * reported using feature byte 0, bit 0. If this extension is
606 * supported, then the implementation provides a means to
607 * report a normal exit with a nonzero exit status in both 32-bit
608 * and 64-bit semihosting APIs.
610 * The implementation must provide the semihosting call
611 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
613 * SYS_EXIT_EXTENDED is used by an application to report an
614 * exception or exit to the debugger directly. The most common
615 * use is to report that execution has completed, using
616 * ADP_Stopped_ApplicationExit.
619 * On entry, the PARAMETER REGISTER contains a pointer to a
620 * two-field argument block:
621 * - field 1 The exception type, which should be one of the set
622 * of reason codes that are documented for the SYS_EXIT
623 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
624 * - field 2 A subcode, whose meaning depends on the reason
625 * code in field 1. In particular, if field 1 is
626 * ADP_Stopped_ApplicationExit then field 2 is an exit status
627 * code, as passed to the C standard library exit() function.
628 * A simulator receiving this request must notify a connected
629 * debugger, if present, and then exit with the specified status.
632 * No return is expected from these calls.
634 * For the A64 API, this call is identical to the behavior of
635 * the mandatory SYS_EXIT (0x18) call. If this extension is
636 * supported, then both calls must be implemented.
638 retval
= semihosting_read_fields(target
, 2, fields
);
639 if (retval
!= ERROR_OK
)
642 int type
= semihosting_get_field(target
, 0, fields
);
643 int code
= semihosting_get_field(target
, 1, fields
);
645 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
646 if (!gdb_get_actual_connections())
650 "semihosting: *** application exited with %d ***\n",
654 fprintf(stderr
, "semihosting: exception %#x\n",
658 if (!semihosting
->has_resumable_exit
) {
659 semihosting
->is_resumable
= false;
660 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
664 case SEMIHOSTING_SYS_FLEN
: /* 0x0C */
666 * Returns the length of a specified file.
669 * On entry, the PARAMETER REGISTER contains a pointer to a
670 * one-field argument block:
671 * - field 1 A handle for a previously opened, seekable file
675 * On exit, the RETURN REGISTER contains:
676 * - The current length of the file object, if the call is
678 * - –1 if an error occurs.
680 if (semihosting
->is_fileio
) {
681 semihosting
->result
= -1;
682 semihosting
->sys_errno
= EINVAL
;
684 retval
= semihosting_read_fields(target
, 1, fields
);
685 if (retval
!= ERROR_OK
)
688 int fd
= semihosting_get_field(target
, 0, fields
);
690 semihosting
->result
= fstat(fd
, &buf
);
691 if (semihosting
->result
== -1) {
692 semihosting
->sys_errno
= errno
;
693 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
696 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
697 semihosting
->result
= buf
.st_size
;
701 case SEMIHOSTING_SYS_GET_CMDLINE
: /* 0x15 */
703 * Returns the command line that is used for the call to the
704 * executable, that is, argc and argv.
707 * On entry, the PARAMETER REGISTER points to a two-field data
708 * block to be used for returning the command string and its length:
709 * - field 1 A pointer to a buffer of at least the size that is
710 * specified in field 2.
711 * - field 2 The length of the buffer in bytes.
715 * If the call is successful, then the RETURN REGISTER contains 0,
716 * the PARAMETER REGISTER is unchanged, and the data block is
717 * updated as follows:
718 * - field 1 A pointer to a null-terminated string of the command
720 * - field 2 The length of the string in bytes.
721 * If the call is not successful, then the RETURN REGISTER
724 * Note: The semihosting implementation might impose limits on
725 * the maximum length of the string that can be transferred.
726 * However, the implementation must be able to support a
727 * command-line length of at least 80 bytes.
729 retval
= semihosting_read_fields(target
, 2, fields
);
730 if (retval
!= ERROR_OK
)
733 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
734 size_t size
= semihosting_get_field(target
, 1, fields
);
736 char *arg
= semihosting
->cmdline
?
737 semihosting
->cmdline
: "";
738 uint32_t len
= strlen(arg
) + 1;
740 semihosting
->result
= -1;
742 semihosting_set_field(target
, len
, 1, fields
);
743 retval
= target_write_buffer(target
, addr
, len
,
745 if (retval
!= ERROR_OK
)
747 semihosting
->result
= 0;
749 retval
= semihosting_write_fields(target
, 2, fields
);
750 if (retval
!= ERROR_OK
)
753 LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64
, arg
, semihosting
->result
);
757 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
759 * Returns the system stack and heap parameters.
762 * On entry, the PARAMETER REGISTER contains the address of a
763 * pointer to a four-field data block. The contents of the data
764 * block are filled by the function. The following C-like
765 * pseudocode describes the layout of the block:
774 * On exit, the PARAMETER REGISTER is unchanged and the data
775 * block has been updated.
777 retval
= semihosting_read_fields(target
, 1, fields
);
778 if (retval
!= ERROR_OK
)
781 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
782 /* tell the remote we have no idea */
783 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
784 retval
= target_write_memory(target
, addr
, 4,
785 semihosting
->word_size_bytes
,
787 if (retval
!= ERROR_OK
)
789 semihosting
->result
= 0;
793 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
795 * Determines whether the return code from another semihosting
796 * call is an error status or not.
798 * This call is passed a parameter block containing the error
802 * On entry, the PARAMETER REGISTER contains a pointer to a
803 * one-field data block:
804 * - field 1 The required status word to check.
807 * On exit, the RETURN REGISTER contains:
808 * - 0 if the status field is not an error indication
809 * - A nonzero value if the status field is an error indication.
811 retval
= semihosting_read_fields(target
, 1, fields
);
812 if (retval
!= ERROR_OK
)
815 uint64_t code
= semihosting_get_field(target
, 0, fields
);
816 semihosting
->result
= (code
!= 0);
819 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
821 * Checks whether a file is connected to an interactive device.
824 * On entry, the PARAMETER REGISTER contains a pointer to a
825 * one-field argument block:
826 * field 1 A handle for a previously opened file object.
829 * On exit, the RETURN REGISTER contains:
830 * - 1 if the handle identifies an interactive device.
831 * - 0 if the handle identifies a file.
832 * - A value other than 1 or 0 if an error occurs.
834 if (semihosting
->is_fileio
) {
835 semihosting
->hit_fileio
= true;
836 fileio_info
->identifier
= "isatty";
837 fileio_info
->param_1
= semihosting
->param
;
839 retval
= semihosting_read_fields(target
, 1, fields
);
840 if (retval
!= ERROR_OK
)
842 int fd
= semihosting_get_field(target
, 0, fields
);
843 // isatty() on Windows may return any non-zero value if fd is a terminal
844 semihosting
->result
= isatty(fd
) ? 1 : 0;
845 if (semihosting
->result
== 0)
846 semihosting
->sys_errno
= errno
;
847 LOG_DEBUG("isatty(%d)=%" PRId64
, fd
, semihosting
->result
);
851 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
853 * Opens a file on the host system.
855 * The file path is specified either as relative to the current
856 * directory of the host process, or absolute, using the path
857 * conventions of the host operating system.
859 * Semihosting implementations must support opening the special
860 * path name :semihosting-features as part of the semihosting
861 * extensions reporting mechanism.
863 * ARM targets interpret the special path name :tt as meaning
864 * the console input stream, for an open-read or the console
865 * output stream, for an open-write. Opening these streams is
866 * performed as part of the standard startup code for those
867 * applications that reference the C stdio streams. The
868 * semihosting extension SH_EXT_STDOUT_STDERR allows the
869 * semihosting caller to open separate output streams
870 * corresponding to stdout and stderr. This extension is
871 * reported using feature byte 0, bit 1. Use SYS_OPEN with
872 * the special path name :semihosting-features to access the
875 * If this extension is supported, the implementation must
876 * support the following additional semantics to SYS_OPEN:
877 * - If the special path name :tt is opened with an fopen
878 * mode requesting write access (w, wb, w+, or w+b), then
879 * this is a request to open stdout.
880 * - If the special path name :tt is opened with a mode
881 * requesting append access (a, ab, a+, or a+b), then this is
882 * a request to open stderr.
885 * On entry, the PARAMETER REGISTER contains a pointer to a
886 * three-field argument block:
887 * - field 1 A pointer to a null-terminated string containing
888 * a file or device name.
889 * - field 2 An integer that specifies the file opening mode.
890 * - field 3 An integer that gives the length of the string
891 * pointed to by field 1.
893 * The length does not include the terminating null character
894 * that must be present.
897 * On exit, the RETURN REGISTER contains:
898 * - A nonzero handle if the call is successful.
899 * - –1 if the call is not successful.
901 retval
= semihosting_read_fields(target
, 3, fields
);
902 if (retval
!= ERROR_OK
)
905 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
906 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
907 size_t len
= semihosting_get_field(target
, 2, fields
);
910 semihosting
->result
= -1;
911 semihosting
->sys_errno
= EINVAL
;
914 size_t basedir_len
= semihosting
->basedir
? strlen(semihosting
->basedir
) : 0;
915 uint8_t *fn
= malloc(basedir_len
+ len
+ 2);
917 semihosting
->result
= -1;
918 semihosting
->sys_errno
= ENOMEM
;
920 if (basedir_len
> 0) {
921 strcpy((char *)fn
, semihosting
->basedir
);
922 if (fn
[basedir_len
- 1] != '/')
923 fn
[basedir_len
++] = '/';
925 retval
= target_read_memory(target
, addr
, 1, len
, fn
+ basedir_len
);
926 if (retval
!= ERROR_OK
) {
930 fn
[basedir_len
+ len
] = 0;
931 /* TODO: implement the :semihosting-features special file.
933 if (semihosting
->is_fileio
) {
934 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
935 semihosting
->result
= -1;
936 semihosting
->sys_errno
= EINVAL
;
937 } else if (strcmp((char *)fn
, ":tt") == 0) {
939 semihosting
->result
= 0;
940 } else if (mode
== 4) {
941 semihosting
->result
= 1;
942 } else if (mode
== 8) {
943 semihosting
->result
= 2;
945 semihosting
->result
= -1;
946 semihosting
->sys_errno
= EINVAL
;
949 semihosting
->hit_fileio
= true;
950 fileio_info
->identifier
= "open";
951 fileio_info
->param_1
= addr
;
952 fileio_info
->param_2
= len
;
953 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
954 fileio_info
->param_4
= 0644;
957 if (strcmp((char *)fn
, ":tt") == 0) {
959 * - 0-3 ("r") for stdin,
960 * - 4-7 ("w") for stdout,
961 * - 8-11 ("a") for stderr */
964 fd
= dup(STDIN_FILENO
);
965 semihosting
->stdin_fd
= fd
;
966 LOG_DEBUG("dup(STDIN)=%d", fd
);
967 } else if (mode
< 8) {
968 fd
= dup(STDOUT_FILENO
);
969 semihosting
->stdout_fd
= fd
;
970 LOG_DEBUG("dup(STDOUT)=%d", fd
);
972 fd
= dup(STDERR_FILENO
);
973 semihosting
->stderr_fd
= fd
;
974 LOG_DEBUG("dup(STDERR)=%d", fd
);
976 semihosting
->result
= fd
;
978 semihosting
->sys_errno
= errno
;
980 /* cygwin requires the permission setting
981 * otherwise it will fail to reopen a previously
983 semihosting
->result
= open((char *)fn
,
984 open_host_modeflags
[mode
],
986 if (semihosting
->result
== -1)
987 semihosting
->sys_errno
= errno
;
988 LOG_DEBUG("open('%s')=%" PRId64
, fn
, semihosting
->result
);
996 case SEMIHOSTING_SYS_READ
: /* 0x06 */
998 * Reads the contents of a file into a buffer. The file position
999 * is specified either:
1000 * - Explicitly by a SYS_SEEK.
1001 * - Implicitly one byte beyond the previous SYS_READ or
1002 * SYS_WRITE request.
1004 * The file position is at the start of the file when it is
1005 * opened, and is lost when the file is closed. Perform the
1006 * file operation as a single action whenever possible. For
1007 * example, do not split a read of 16KB into four 4KB chunks
1008 * unless there is no alternative.
1011 * On entry, the PARAMETER REGISTER contains a pointer to a
1012 * three-field data block:
1013 * - field 1 Contains a handle for a file previously opened
1015 * - field 2 Points to a buffer.
1016 * - field 3 Contains the number of bytes to read to the buffer
1020 * On exit, the RETURN REGISTER contains the number of bytes not
1021 * filled in the buffer (buffer_length - bytes_read) as follows:
1022 * - If the RETURN REGISTER is 0, the entire buffer was
1023 * successfully filled.
1024 * - If the RETURN REGISTER is the same as field 3, no bytes
1025 * were read (EOF can be assumed).
1026 * - If the RETURN REGISTER contains a value smaller than
1027 * field 3, the read succeeded but the buffer was only partly
1028 * filled. For interactive devices, this is the most common
1031 retval
= semihosting_read_fields(target
, 3, fields
);
1032 if (retval
!= ERROR_OK
)
1035 int fd
= semihosting_get_field(target
, 0, fields
);
1036 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1037 size_t len
= semihosting_get_field(target
, 2, fields
);
1038 if (semihosting
->is_fileio
) {
1039 semihosting
->hit_fileio
= true;
1040 fileio_info
->identifier
= "read";
1041 fileio_info
->param_1
= fd
;
1042 fileio_info
->param_2
= addr
;
1043 fileio_info
->param_3
= len
;
1045 uint8_t *buf
= malloc(len
);
1047 semihosting
->result
= -1;
1048 semihosting
->sys_errno
= ENOMEM
;
1050 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
1051 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
1055 semihosting
->result
);
1056 if (semihosting
->result
>= 0) {
1057 retval
= target_write_buffer(target
, addr
,
1058 semihosting
->result
,
1060 if (retval
!= ERROR_OK
) {
1064 /* the number of bytes NOT filled in */
1065 semihosting
->result
= len
-
1066 semihosting
->result
;
1074 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1076 * Reads a byte from the console.
1079 * The PARAMETER REGISTER must contain 0. There are no other
1080 * parameters or values possible.
1083 * On exit, the RETURN REGISTER contains the byte read from
1086 if (semihosting
->is_fileio
) {
1087 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1090 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1091 LOG_DEBUG("getchar()=%" PRId64
, semihosting
->result
);
1094 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1096 * Deletes a specified file on the host filing system.
1099 * On entry, the PARAMETER REGISTER contains a pointer to a
1100 * two-field argument block:
1101 * - field 1 Points to a null-terminated string that gives the
1102 * path name of the file to be deleted.
1103 * - field 2 The length of the string.
1106 * On exit, the RETURN REGISTER contains:
1107 * - 0 if the delete is successful
1108 * - A nonzero, host-specific error code if the delete fails.
1110 retval
= semihosting_read_fields(target
, 2, fields
);
1111 if (retval
!= ERROR_OK
)
1114 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1115 size_t len
= semihosting_get_field(target
, 1, fields
);
1116 if (semihosting
->is_fileio
) {
1117 semihosting
->hit_fileio
= true;
1118 fileio_info
->identifier
= "unlink";
1119 fileio_info
->param_1
= addr
;
1120 fileio_info
->param_2
= len
;
1122 uint8_t *fn
= malloc(len
+1);
1124 semihosting
->result
= -1;
1125 semihosting
->sys_errno
= ENOMEM
;
1128 target_read_memory(target
, addr
, 1, len
,
1130 if (retval
!= ERROR_OK
) {
1135 semihosting
->result
= remove((char *)fn
);
1136 if (semihosting
->result
== -1)
1137 semihosting
->sys_errno
= errno
;
1138 LOG_DEBUG("remove('%s')=%" PRId64
, fn
, semihosting
->result
);
1146 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1148 * Renames a specified file.
1151 * On entry, the PARAMETER REGISTER contains a pointer to a
1152 * four-field data block:
1153 * - field 1 A pointer to the name of the old file.
1154 * - field 2 The length of the old filename.
1155 * - field 3 A pointer to the new filename.
1156 * - field 4 The length of the new filename. Both strings are
1160 * On exit, the RETURN REGISTER contains:
1161 * - 0 if the rename is successful.
1162 * - A nonzero, host-specific error code if the rename fails.
1164 retval
= semihosting_read_fields(target
, 4, fields
);
1165 if (retval
!= ERROR_OK
)
1168 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1169 size_t len1
= semihosting_get_field(target
, 1, fields
);
1170 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1171 size_t len2
= semihosting_get_field(target
, 3, fields
);
1172 if (semihosting
->is_fileio
) {
1173 semihosting
->hit_fileio
= true;
1174 fileio_info
->identifier
= "rename";
1175 fileio_info
->param_1
= addr1
;
1176 fileio_info
->param_2
= len1
;
1177 fileio_info
->param_3
= addr2
;
1178 fileio_info
->param_4
= len2
;
1180 uint8_t *fn1
= malloc(len1
+1);
1181 uint8_t *fn2
= malloc(len2
+1);
1185 semihosting
->result
= -1;
1186 semihosting
->sys_errno
= ENOMEM
;
1188 retval
= target_read_memory(target
, addr1
, 1, len1
,
1190 if (retval
!= ERROR_OK
) {
1195 retval
= target_read_memory(target
, addr2
, 1, len2
,
1197 if (retval
!= ERROR_OK
) {
1204 semihosting
->result
= rename((char *)fn1
,
1206 // rename() on Windows returns nonzero on error
1207 if (semihosting
->result
!= 0)
1208 semihosting
->sys_errno
= errno
;
1209 LOG_DEBUG("rename('%s', '%s')=%" PRId64
" %d", fn1
, fn2
, semihosting
->result
, errno
);
1217 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1219 * Seeks to a specified position in a file using an offset
1220 * specified from the start of the file. The file is assumed
1221 * to be a byte array and the offset is given in bytes.
1224 * On entry, the PARAMETER REGISTER contains a pointer to a
1225 * two-field data block:
1226 * - field 1 A handle for a seekable file object.
1227 * - field 2 The absolute byte position to seek to.
1230 * On exit, the RETURN REGISTER contains:
1231 * - 0 if the request is successful.
1232 * - A negative value if the request is not successful.
1233 * Use SYS_ERRNO to read the value of the host errno variable
1234 * describing the error.
1236 * Note: The effect of seeking outside the current extent of
1237 * the file object is undefined.
1239 retval
= semihosting_read_fields(target
, 2, fields
);
1240 if (retval
!= ERROR_OK
)
1243 int fd
= semihosting_get_field(target
, 0, fields
);
1244 off_t pos
= semihosting_get_field(target
, 1, fields
);
1245 if (semihosting
->is_fileio
) {
1246 semihosting
->hit_fileio
= true;
1247 fileio_info
->identifier
= "lseek";
1248 fileio_info
->param_1
= fd
;
1249 fileio_info
->param_2
= pos
;
1250 fileio_info
->param_3
= SEEK_SET
;
1252 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1253 if (semihosting
->result
== -1)
1254 semihosting
->sys_errno
= errno
;
1255 LOG_DEBUG("lseek(%d, %d)=%" PRId64
, fd
, (int)pos
, semihosting
->result
);
1256 if (semihosting
->result
== pos
)
1257 semihosting
->result
= 0;
1262 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1264 * Passes a command to the host command-line interpreter.
1265 * This enables you to execute a system command such as dir,
1266 * ls, or pwd. The terminal I/O is on the host, and is not
1267 * visible to the target.
1270 * On entry, the PARAMETER REGISTER contains a pointer to a
1271 * two-field argument block:
1272 * - field 1 Points to a string to be passed to the host
1273 * command-line interpreter.
1274 * - field 2 The length of the string.
1277 * On exit, the RETURN REGISTER contains the return status.
1280 /* Provide SYS_SYSTEM functionality. Uses the
1281 * libc system command, there may be a reason *NOT*
1282 * to use this, but as I can't think of one, I
1283 * implemented it this way.
1285 retval
= semihosting_read_fields(target
, 2, fields
);
1286 if (retval
!= ERROR_OK
)
1289 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1290 size_t len
= semihosting_get_field(target
, 1, fields
);
1291 if (semihosting
->is_fileio
) {
1292 semihosting
->hit_fileio
= true;
1293 fileio_info
->identifier
= "system";
1294 fileio_info
->param_1
= addr
;
1295 fileio_info
->param_2
= len
;
1297 uint8_t *cmd
= malloc(len
+1);
1299 semihosting
->result
= -1;
1300 semihosting
->sys_errno
= ENOMEM
;
1302 retval
= target_read_memory(target
,
1307 if (retval
!= ERROR_OK
) {
1312 semihosting
->result
= system(
1314 LOG_DEBUG("system('%s')=%" PRId64
, cmd
, semihosting
->result
);
1323 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1325 * Returns the number of seconds since 00:00 January 1, 1970.
1326 * This value is real-world time, regardless of any debug agent
1330 * There are no parameters.
1333 * On exit, the RETURN REGISTER contains the number of seconds.
1335 semihosting
->result
= time(NULL
);
1338 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1340 * Writes the contents of a buffer to a specified file at the
1341 * current file position. The file position is specified either:
1342 * - Explicitly, by a SYS_SEEK.
1343 * - Implicitly as one byte beyond the previous SYS_READ or
1344 * SYS_WRITE request.
1346 * The file position is at the start of the file when the file
1347 * is opened, and is lost when the file is closed.
1349 * Perform the file operation as a single action whenever
1350 * possible. For example, do not split a write of 16KB into
1351 * four 4KB chunks unless there is no alternative.
1354 * On entry, the PARAMETER REGISTER contains a pointer to a
1355 * three-field data block:
1356 * - field 1 Contains a handle for a file previously opened
1358 * - field 2 Points to the memory containing the data to be written.
1359 * - field 3 Contains the number of bytes to be written from
1360 * the buffer to the file.
1363 * On exit, the RETURN REGISTER contains:
1364 * - 0 if the call is successful.
1365 * - The number of bytes that are not written, if there is an error.
1367 retval
= semihosting_read_fields(target
, 3, fields
);
1368 if (retval
!= ERROR_OK
)
1371 int fd
= semihosting_get_field(target
, 0, fields
);
1372 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1373 size_t len
= semihosting_get_field(target
, 2, fields
);
1374 if (semihosting
->is_fileio
) {
1375 semihosting
->hit_fileio
= true;
1376 fileio_info
->identifier
= "write";
1377 fileio_info
->param_1
= fd
;
1378 fileio_info
->param_2
= addr
;
1379 fileio_info
->param_3
= len
;
1381 uint8_t *buf
= malloc(len
);
1383 semihosting
->result
= -1;
1384 semihosting
->sys_errno
= ENOMEM
;
1386 retval
= target_read_buffer(target
, addr
, len
, buf
);
1387 if (retval
!= ERROR_OK
) {
1391 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1392 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
1396 semihosting
->result
);
1397 if (semihosting
->result
>= 0) {
1398 /* The number of bytes that are NOT written.
1400 semihosting
->result
= len
-
1401 semihosting
->result
;
1410 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1412 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1413 * to the debug channel. When executed under a semihosting
1414 * debugger, the character appears on the host debugger console.
1417 * On entry, the PARAMETER REGISTER contains a pointer to the
1421 * None. The RETURN REGISTER is corrupted.
1423 if (semihosting
->is_fileio
) {
1424 semihosting
->hit_fileio
= true;
1425 fileio_info
->identifier
= "write";
1426 fileio_info
->param_1
= 1;
1427 fileio_info
->param_2
= semihosting
->param
;
1428 fileio_info
->param_3
= 1;
1430 uint64_t addr
= semihosting
->param
;
1432 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1433 if (retval
!= ERROR_OK
)
1435 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1436 semihosting
->result
= 0;
1440 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1442 * Writes a null-terminated string to the debug channel.
1443 * When executed under a semihosting debugger, the characters
1444 * appear on the host debugger console.
1447 * On entry, the PARAMETER REGISTER contains a pointer to the
1448 * first byte of the string.
1451 * None. The RETURN REGISTER is corrupted.
1453 if (semihosting
->is_fileio
) {
1455 uint64_t addr
= semihosting
->param
;
1458 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1459 if (retval
!= ERROR_OK
)
1465 semihosting
->hit_fileio
= true;
1466 fileio_info
->identifier
= "write";
1467 fileio_info
->param_1
= 1;
1468 fileio_info
->param_2
= semihosting
->param
;
1469 fileio_info
->param_3
= count
;
1471 uint64_t addr
= semihosting
->param
;
1474 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1475 if (retval
!= ERROR_OK
)
1479 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1481 semihosting
->result
= 0;
1485 case SEMIHOSTING_USER_CMD_0X100
... SEMIHOSTING_USER_CMD_0X107
:
1487 * This is a user defined operation (while user cmds 0x100-0x1ff
1488 * are possible, only 0x100-0x107 are currently implemented).
1490 * Reads the user operation parameters from target, then fires the
1491 * corresponding target event. When the target callbacks returned,
1492 * cleans up the command parameter buffer.
1495 * On entry, the PARAMETER REGISTER contains a pointer to a
1496 * two-field data block:
1497 * - field 1 Contains a pointer to the bound command parameter
1499 * - field 2 Contains the command parameter string length
1502 * On exit, the RETURN REGISTER contains the return status.
1504 if (semihosting
->user_command_extension
) {
1505 retval
= semihosting
->user_command_extension(target
);
1506 if (retval
!= ERROR_NOT_IMPLEMENTED
)
1508 /* If custom user command not handled, we are looking for the TCL handler */
1511 assert(!semihosting_user_op_params
);
1512 retval
= semihosting_read_fields(target
, 2, fields
);
1513 if (retval
!= ERROR_OK
) {
1514 LOG_ERROR("Failed to read fields for user defined command"
1515 " op=0x%x", semihosting
->op
);
1519 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1521 size_t len
= semihosting_get_field(target
, 1, fields
);
1522 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1523 LOG_ERROR("The maximum length for user defined command "
1524 "parameter is %u, received length is %zu (op=0x%x)",
1525 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1531 semihosting_user_op_params
= malloc(len
+ 1);
1532 if (!semihosting_user_op_params
)
1534 semihosting_user_op_params
[len
] = 0;
1536 retval
= target_read_buffer(target
, addr
, len
,
1537 (uint8_t *)(semihosting_user_op_params
));
1538 if (retval
!= ERROR_OK
) {
1539 LOG_ERROR("Failed to read from target, semihosting op=0x%x (%s)",
1541 semihosting_opcode_to_str(semihosting
->op
));
1542 free(semihosting_user_op_params
);
1543 semihosting_user_op_params
= NULL
;
1547 target_handle_event(target
, semihosting
->op
);
1548 free(semihosting_user_op_params
);
1549 semihosting_user_op_params
= NULL
;
1550 semihosting
->result
= 0;
1553 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1555 * Returns the number of elapsed target ticks since execution
1557 * Use SYS_TICKFREQ to determine the tick frequency.
1560 * On entry, the PARAMETER REGISTER points to a two-field data
1561 * block to be used for returning the number of elapsed ticks:
1562 * - field 1 The least significant field and is at the low address.
1563 * - field 2 The most significant field and is at the high address.
1566 * On entry the PARAMETER REGISTER points to a one-field data
1567 * block to be used for returning the number of elapsed ticks:
1568 * - field 1 The number of elapsed ticks as a 64-bit value.
1572 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1573 * REGISTER is unchanged, and the data block pointed to by the
1574 * PARAMETER REGISTER is filled in with the number of elapsed
1576 * - On failure, the RETURN REGISTER contains -1, and the
1577 * PARAMETER REGISTER contains -1.
1579 * Note: Some semihosting implementations might not support this
1580 * semihosting operation, and they always return -1 in the
1584 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1586 * Returns the tick frequency.
1589 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1592 * On exit, the RETURN REGISTER contains either:
1593 * - The number of ticks per second.
1594 * - –1 if the target does not know the value of one tick.
1596 * Note: Some semihosting implementations might not support
1597 * this semihosting operation, and they always return -1 in the
1601 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1603 * Returns a temporary name for a file identified by a system
1607 * On entry, the PARAMETER REGISTER contains a pointer to a
1608 * three-word argument block:
1609 * - field 1 A pointer to a buffer.
1610 * - field 2 A target identifier for this filename. Its value
1611 * must be an integer in the range 0-255.
1612 * - field 3 Contains the length of the buffer. The length must
1613 * be at least the value of L_tmpnam on the host system.
1616 * On exit, the RETURN REGISTER contains:
1617 * - 0 if the call is successful.
1618 * - –1 if an error occurs.
1620 * The buffer pointed to by the PARAMETER REGISTER contains
1621 * the filename, prefixed with a suitable directory name.
1622 * If you use the same target identifier again, the same
1623 * filename is returned.
1625 * Note: The returned string must be null-terminated.
1629 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1630 (unsigned) semihosting
->op
);
1631 semihosting
->result
= -1;
1632 semihosting
->sys_errno
= ENOTSUP
;
1635 if (!semihosting
->hit_fileio
) {
1636 retval
= semihosting
->post_result(target
);
1637 if (retval
!= ERROR_OK
) {
1638 LOG_ERROR("Failed to post semihosting result");
1646 /* -------------------------------------------------------------------------
1647 * Local functions. */
1649 static int semihosting_common_fileio_info(struct target
*target
,
1650 struct gdb_fileio_info
*fileio_info
)
1652 struct semihosting
*semihosting
= target
->semihosting
;
1657 * To avoid unnecessary duplication, semihosting prepares the
1658 * fileio_info structure out-of-band when the target halts. See
1659 * do_semihosting for more detail.
1661 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1667 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1668 int fileio_errno
, bool ctrl_c
)
1670 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1671 struct semihosting
*semihosting
= target
->semihosting
;
1675 /* clear pending status */
1676 semihosting
->hit_fileio
= false;
1678 semihosting
->result
= result
;
1681 * Some fileio results do not match up with what the semihosting
1682 * operation expects; for these operations, we munge the results
1685 switch (semihosting
->op
) {
1686 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1687 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1689 semihosting
->result
= fileio_info
->param_3
; /* Zero bytes read/written. */
1691 semihosting
->result
= (int64_t)fileio_info
->param_3
- result
;
1694 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1696 semihosting
->result
= 0;
1700 bool fileio_failed
= false;
1701 if (semihosting
->op
== SEMIHOSTING_SYS_ISTTY
)
1702 fileio_failed
= (semihosting
->result
== 0);
1703 else if (semihosting
->op
== SEMIHOSTING_SYS_RENAME
)
1704 fileio_failed
= (semihosting
->result
!= 0);
1706 fileio_failed
= (semihosting
->result
== -1);
1709 semihosting
->sys_errno
= fileio_errno
;
1711 return semihosting
->post_result(target
);
1714 /* -------------------------------------------------------------------------
1715 * Utility functions. */
1718 * Read all fields of a command from target to buffer.
1720 int semihosting_read_fields(struct target
*target
, size_t number
,
1723 struct semihosting
*semihosting
= target
->semihosting
;
1724 /* Use 4-byte multiples to trigger fast memory access. */
1725 return target_read_memory(target
, semihosting
->param
, 4,
1726 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1730 * Write all fields of a command from buffer to target.
1732 int semihosting_write_fields(struct target
*target
, size_t number
,
1735 struct semihosting
*semihosting
= target
->semihosting
;
1736 /* Use 4-byte multiples to trigger fast memory access. */
1737 return target_write_memory(target
, semihosting
->param
, 4,
1738 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1742 * Extract a field from the buffer, considering register size and endianness.
1744 uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1747 struct semihosting
*semihosting
= target
->semihosting
;
1748 if (semihosting
->word_size_bytes
== 8)
1749 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1751 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1755 * Store a field in the buffer, considering register size and endianness.
1757 void semihosting_set_field(struct target
*target
, uint64_t value
,
1761 struct semihosting
*semihosting
= target
->semihosting
;
1762 if (semihosting
->word_size_bytes
== 8)
1763 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1765 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1768 /* -------------------------------------------------------------------------
1769 * Semihosting redirect over TCP structs and functions */
1771 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1773 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1774 service
->semihosting
->tcp_connection
= connection
;
1779 static int semihosting_service_input_handler(struct connection
*connection
)
1781 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1783 if (!connection
->input_pending
) {
1784 /* consume received data, not for semihosting IO */
1785 const int buf_len
= 100;
1787 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1789 if (bytes_read
== 0) {
1790 return ERROR_SERVER_REMOTE_CLOSED
;
1791 } else if (bytes_read
== -1) {
1792 LOG_ERROR("error during read: %s", strerror(errno
));
1793 return ERROR_SERVER_REMOTE_CLOSED
;
1795 } else if (service
->error
!= ERROR_OK
) {
1796 return ERROR_SERVER_REMOTE_CLOSED
;
1802 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1804 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1806 free(service
->name
);
1811 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1813 if (!semihosting
->tcp_connection
)
1816 struct service
*service
= semihosting
->tcp_connection
->service
;
1817 remove_service(service
->name
, service
->port
);
1818 semihosting
->tcp_connection
= NULL
;
1822 static const struct service_driver semihosting_service_driver
= {
1823 .name
= "semihosting",
1824 .new_connection_during_keep_alive_handler
= NULL
,
1825 .new_connection_handler
= semihosting_service_new_connection_handler
,
1826 .input_handler
= semihosting_service_input_handler
,
1827 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1828 .keep_client_alive_handler
= NULL
,
1831 /* -------------------------------------------------------------------------
1832 * Common semihosting commands handlers. */
1834 COMMAND_HANDLER(handle_common_semihosting_command
)
1836 struct target
*target
= get_current_target(CMD_CTX
);
1839 LOG_ERROR("No target selected");
1843 struct semihosting
*semihosting
= target
->semihosting
;
1845 command_print(CMD
, "semihosting not supported for current target");
1852 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1854 if (!target_was_examined(target
)) {
1855 LOG_ERROR("Target not examined yet");
1859 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1860 LOG_ERROR("Failed to Configure semihosting");
1864 /* FIXME never let that "catch" be dropped! (???) */
1865 semihosting
->is_active
= is_active
;
1868 command_print(CMD
, "semihosting is %s",
1869 semihosting
->is_active
1870 ? "enabled" : "disabled");
1875 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1877 struct target
*target
= get_current_target(CMD_CTX
);
1880 LOG_ERROR("No target selected");
1884 struct semihosting
*semihosting
= target
->semihosting
;
1886 command_print(CMD
, "semihosting not supported for current target");
1890 if (!semihosting
->is_active
) {
1891 command_print(CMD
, "semihosting not yet enabled for current target");
1895 enum semihosting_redirect_config cfg
;
1899 return ERROR_COMMAND_SYNTAX_ERROR
;
1901 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1902 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1904 return ERROR_COMMAND_SYNTAX_ERROR
;
1905 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1906 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1907 return ERROR_COMMAND_SYNTAX_ERROR
;
1911 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1912 if (CMD_ARGC
== 3) {
1913 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1914 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1915 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1916 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1917 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1918 return ERROR_COMMAND_SYNTAX_ERROR
;
1921 return ERROR_COMMAND_SYNTAX_ERROR
;
1924 semihosting_tcp_close_cnx(semihosting
);
1925 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1927 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1928 struct semihosting_tcp_service
*service
=
1929 calloc(1, sizeof(struct semihosting_tcp_service
));
1931 LOG_ERROR("Failed to allocate semihosting TCP service.");
1935 service
->semihosting
= semihosting
;
1937 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1938 if (!service
->name
) {
1939 LOG_ERROR("Out of memory");
1944 int ret
= add_service(&semihosting_service_driver
,
1947 if (ret
!= ERROR_OK
) {
1948 LOG_ERROR("failed to initialize %s", service
->name
);
1949 free(service
->name
);
1955 semihosting
->redirect_cfg
= cfg
;
1960 COMMAND_HANDLER(handle_common_semihosting_fileio_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
->is_fileio
);
1983 command_print(CMD
, "semihosting fileio is %s",
1984 semihosting
->is_fileio
1985 ? "enabled" : "disabled");
1990 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1992 struct target
*target
= get_current_target(CMD_CTX
);
1996 LOG_ERROR("No target selected");
2000 struct semihosting
*semihosting
= target
->semihosting
;
2002 command_print(CMD
, "semihosting not supported for current target");
2006 free(semihosting
->cmdline
);
2007 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
2009 for (i
= 1; i
< CMD_ARGC
; i
++) {
2010 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
2013 free(semihosting
->cmdline
);
2014 semihosting
->cmdline
= cmdline
;
2017 command_print(CMD
, "semihosting command line is [%s]",
2018 semihosting
->cmdline
);
2023 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
2025 struct target
*target
= get_current_target(CMD_CTX
);
2028 LOG_ERROR("No target selected");
2032 struct semihosting
*semihosting
= target
->semihosting
;
2034 command_print(CMD
, "semihosting not supported for current target");
2038 if (!semihosting
->is_active
) {
2039 command_print(CMD
, "semihosting not yet enabled for current target");
2044 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
2046 command_print(CMD
, "semihosting resumable exit is %s",
2047 semihosting
->has_resumable_exit
2048 ? "enabled" : "disabled");
2053 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
2055 struct target
*target
= get_current_target(CMD_CTX
);
2056 struct semihosting
*semihosting
= target
->semihosting
;
2059 return ERROR_COMMAND_SYNTAX_ERROR
;
2061 if (!semihosting
->is_active
) {
2062 LOG_ERROR("semihosting not yet enabled for current target");
2066 if (!semihosting_user_op_params
) {
2067 LOG_ERROR("This command is usable only from a registered user "
2068 "semihosting event callback.");
2072 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2077 COMMAND_HANDLER(handle_common_semihosting_basedir_command
)
2079 struct target
*target
= get_current_target(CMD_CTX
);
2082 return ERROR_COMMAND_SYNTAX_ERROR
;
2085 LOG_ERROR("No target selected");
2089 struct semihosting
*semihosting
= target
->semihosting
;
2091 command_print(CMD
, "semihosting not supported for current target");
2095 if (!semihosting
->is_active
) {
2096 command_print(CMD
, "semihosting not yet enabled for current target");
2101 free(semihosting
->basedir
);
2102 semihosting
->basedir
= strdup(CMD_ARGV
[0]);
2103 if (!semihosting
->basedir
) {
2104 command_print(CMD
, "semihosting failed to allocate memory for basedir!");
2109 command_print(CMD
, "semihosting base dir: %s",
2110 semihosting
->basedir
? semihosting
->basedir
: "");
2115 const struct command_registration semihosting_common_handlers
[] = {
2117 .name
= "semihosting",
2118 .handler
= handle_common_semihosting_command
,
2119 .mode
= COMMAND_EXEC
,
2120 .usage
= "['enable'|'disable']",
2121 .help
= "activate support for semihosting operations",
2124 .name
= "semihosting_redirect",
2125 .handler
= handle_common_semihosting_redirect_command
,
2126 .mode
= COMMAND_EXEC
,
2127 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2128 .help
= "redirect semihosting IO",
2131 .name
= "semihosting_cmdline",
2132 .handler
= handle_common_semihosting_cmdline
,
2133 .mode
= COMMAND_EXEC
,
2134 .usage
= "arguments",
2135 .help
= "command line arguments to be passed to program",
2138 .name
= "semihosting_fileio",
2139 .handler
= handle_common_semihosting_fileio_command
,
2140 .mode
= COMMAND_EXEC
,
2141 .usage
= "['enable'|'disable']",
2142 .help
= "activate support for semihosting fileio operations",
2145 .name
= "semihosting_resexit",
2146 .handler
= handle_common_semihosting_resumable_exit_command
,
2147 .mode
= COMMAND_EXEC
,
2148 .usage
= "['enable'|'disable']",
2149 .help
= "activate support for semihosting resumable exit",
2152 .name
= "semihosting_read_user_param",
2153 .handler
= handle_common_semihosting_read_user_param_command
,
2154 .mode
= COMMAND_EXEC
,
2156 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2159 .name
= "semihosting_basedir",
2160 .handler
= handle_common_semihosting_basedir_command
,
2161 .mode
= COMMAND_EXEC
,
2163 .help
= "set the base directory for semihosting I/O operations",
2165 COMMAND_REGISTRATION_DONE