1 /***************************************************************************
2 * Copyright (C) 2018 by Liviu Ionescu *
5 * Copyright (C) 2018 by Marvell Technology Group Ltd. *
6 * Written by Nicolas Pitre <nico@marvell.com> *
8 * Copyright (C) 2010 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2016 by Square, Inc. *
12 * Steven Stallion <stallion@squareup.com> *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
26 ***************************************************************************/
30 * Common ARM semihosting support.
32 * Semihosting enables code running on a target to use some of the I/O
33 * facilities on the host computer. The target application must be linked
34 * against a library that forwards operation requests by using an
35 * instruction trapped by the debugger.
37 * Details can be found in
38 * "Semihosting for AArch32 and AArch64, Release 2.0"
39 * https://static.docs.arm.com/100863/0200/semihosting.pdf
48 #include "target_type.h"
49 #include "semihosting_common.h"
51 #include <helper/binarybuffer.h>
52 #include <helper/log.h>
56 * It is not possible to use O_... flags defined in sys/stat.h because they
57 * are not guaranteed to match the values defined by the GDB Remote Protocol.
58 * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
61 TARGET_O_RDONLY
= 0x000,
62 TARGET_O_WRONLY
= 0x001,
63 TARGET_O_RDWR
= 0x002,
64 TARGET_O_APPEND
= 0x008,
65 TARGET_O_CREAT
= 0x200,
66 TARGET_O_TRUNC
= 0x400,
67 /* O_EXCL=0x800 is not required in this implementation. */
70 /* GDB remote protocol does not differentiate between text and binary open modes. */
71 static const int open_gdb_modeflags
[12] = {
76 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
77 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
78 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
79 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
80 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
81 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
82 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
,
83 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
86 static const int open_host_modeflags
[12] = {
91 O_WRONLY
| O_CREAT
| O_TRUNC
,
92 O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
93 O_RDWR
| O_CREAT
| O_TRUNC
,
94 O_RDWR
| O_CREAT
| O_TRUNC
| O_BINARY
,
95 O_WRONLY
| O_CREAT
| O_APPEND
,
96 O_WRONLY
| O_CREAT
| O_APPEND
| O_BINARY
,
97 O_RDWR
| O_CREAT
| O_APPEND
,
98 O_RDWR
| O_CREAT
| O_APPEND
| O_BINARY
101 static int semihosting_common_fileio_info(struct target
*target
,
102 struct gdb_fileio_info
*fileio_info
);
103 static int semihosting_common_fileio_end(struct target
*target
, int result
,
104 int fileio_errno
, bool ctrl_c
);
106 static int semihosting_read_fields(struct target
*target
, size_t number
,
108 static int semihosting_write_fields(struct target
*target
, size_t number
,
110 static uint64_t semihosting_get_field(struct target
*target
, size_t index
,
112 static void semihosting_set_field(struct target
*target
, uint64_t value
,
116 /* Attempts to include gdb_server.h failed. */
117 extern int gdb_actual_connections
;
120 * Initialize common semihosting support.
122 * @param target Pointer to the target to initialize.
125 * @return An error status if there is a problem during initialization.
127 int semihosting_common_init(struct target
*target
, void *setup
,
132 target
->fileio_info
= malloc(sizeof(*target
->fileio_info
));
133 if (!target
->fileio_info
) {
134 LOG_ERROR("out of memory");
137 memset(target
->fileio_info
, 0, sizeof(*target
->fileio_info
));
139 struct semihosting
*semihosting
;
140 semihosting
= malloc(sizeof(*target
->semihosting
));
142 LOG_ERROR("out of memory");
146 semihosting
->is_active
= false;
147 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
148 semihosting
->tcp_connection
= NULL
;
149 semihosting
->stdin_fd
= -1;
150 semihosting
->stdout_fd
= -1;
151 semihosting
->stderr_fd
= -1;
152 semihosting
->is_fileio
= false;
153 semihosting
->hit_fileio
= false;
154 semihosting
->is_resumable
= false;
155 semihosting
->has_resumable_exit
= false;
156 semihosting
->word_size_bytes
= 0;
157 semihosting
->op
= -1;
158 semihosting
->param
= 0;
159 semihosting
->result
= -1;
160 semihosting
->sys_errno
= -1;
161 semihosting
->cmdline
= NULL
;
162 semihosting
->basedir
= NULL
;
164 /* If possible, update it in setup(). */
165 semihosting
->setup_time
= clock();
167 semihosting
->setup
= setup
;
168 semihosting
->post_result
= post_result
;
170 target
->semihosting
= semihosting
;
172 target
->type
->get_gdb_fileio_info
= semihosting_common_fileio_info
;
173 target
->type
->gdb_fileio_end
= semihosting_common_fileio_end
;
178 struct semihosting_tcp_service
{
179 struct semihosting
*semihosting
;
184 static bool semihosting_is_redirected(struct semihosting
*semihosting
, int fd
)
186 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_NONE
)
189 bool is_read_op
= false;
191 switch (semihosting
->op
) {
192 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
193 case SEMIHOSTING_SYS_READC
:
196 case SEMIHOSTING_SYS_WRITEC
:
197 case SEMIHOSTING_SYS_WRITE0
:
198 /* debug operations are redirected when CFG is either DEBUG or ALL */
199 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_STDIO
)
203 /* check stdio semihosting operations: READ and WRITE */
204 case SEMIHOSTING_SYS_READ
:
207 case SEMIHOSTING_SYS_WRITE
:
208 /* stdio operations are redirected when CFG is either STDIO or ALL */
209 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_DEBUG
)
218 return fd
== semihosting
->stdin_fd
;
220 /* write operation */
221 return fd
== semihosting
->stdout_fd
|| fd
== semihosting
->stderr_fd
;
224 static ssize_t
semihosting_redirect_write(struct semihosting
*semihosting
, void *buf
, int size
)
226 if (!semihosting
->tcp_connection
) {
227 LOG_ERROR("No connected TCP client for semihosting");
228 semihosting
->sys_errno
= EBADF
; /* Bad file number */
232 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
234 int retval
= connection_write(semihosting
->tcp_connection
, buf
, size
);
237 log_socket_error(service
->name
);
242 static ssize_t
semihosting_write(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
244 if (semihosting_is_redirected(semihosting
, fd
))
245 return semihosting_redirect_write(semihosting
, buf
, size
);
248 return write(fd
, buf
, size
);
251 static ssize_t
semihosting_redirect_read(struct semihosting
*semihosting
, void *buf
, int size
)
253 if (!semihosting
->tcp_connection
) {
254 LOG_ERROR("No connected TCP client for semihosting");
255 semihosting
->sys_errno
= EBADF
; /* Bad file number */
259 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
261 service
->error
= ERROR_OK
;
262 semihosting
->tcp_connection
->input_pending
= true;
264 int retval
= connection_read(semihosting
->tcp_connection
, buf
, size
);
267 service
->error
= ERROR_SERVER_REMOTE_CLOSED
;
270 log_socket_error(service
->name
);
272 semihosting
->tcp_connection
->input_pending
= false;
277 static inline int semihosting_putchar(struct semihosting
*semihosting
, int fd
, int c
)
279 if (semihosting_is_redirected(semihosting
, fd
))
280 return semihosting_redirect_write(semihosting
, &c
, 1);
282 /* default putchar */
286 static inline ssize_t
semihosting_read(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
288 if (semihosting_is_redirected(semihosting
, fd
))
289 return semihosting_redirect_read(semihosting
, buf
, size
);
292 ssize_t result
= read(fd
, buf
, size
);
293 semihosting
->sys_errno
= errno
;
298 static inline int semihosting_getchar(struct semihosting
*semihosting
, int fd
)
300 if (semihosting_is_redirected(semihosting
, fd
)) {
303 if (semihosting_redirect_read(semihosting
, &c
, 1) > 0)
309 /* default getchar */
314 * User operation parameter string storage buffer. Contains valid data when the
315 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
317 static char *semihosting_user_op_params
;
320 * Portable implementation of ARM semihosting calls.
321 * Performs the currently pending semihosting operation
322 * encoded in target->semihosting.
324 int semihosting_common(struct target
*target
)
326 struct semihosting
*semihosting
= target
->semihosting
;
328 /* Silently ignore if the semihosting field was not set. */
332 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
335 * By default return an error.
336 * The actual result must be set by each function
338 semihosting
->result
= -1;
340 /* Most operations are resumable, except the two exit calls. */
341 semihosting
->is_resumable
= true;
345 /* Enough space to hold 4 long words. */
348 LOG_DEBUG("op=0x%x, param=0x%" PRIx64
, semihosting
->op
,
351 switch (semihosting
->op
) {
353 case SEMIHOSTING_SYS_CLOCK
: /* 0x10 */
355 * Returns the number of centiseconds (hundredths of a second)
356 * since the execution started.
358 * Values returned can be of limited use for some benchmarking
359 * purposes because of communication overhead or other
360 * agent-specific factors. For example, with a debug hardware
361 * unit the request is passed back to the host for execution.
362 * This can lead to unpredictable delays in transmission and
363 * process scheduling.
365 * Use this function to calculate time intervals, by calculating
366 * differences between intervals with and without the code
367 * sequence to be timed.
370 * The PARAMETER REGISTER must contain 0. There are no other
374 * On exit, the RETURN REGISTER contains:
375 * - The number of centiseconds since some arbitrary start
376 * point, if the call is successful.
377 * - –1 if the call is not successful. For example, because
378 * of a communications error.
381 clock_t delta
= clock() - semihosting
->setup_time
;
383 semihosting
->result
= delta
/ (CLOCKS_PER_SEC
/ 100);
387 case SEMIHOSTING_SYS_CLOSE
: /* 0x02 */
389 * Closes a file on the host system. The handle must reference
390 * a file that was opened with SYS_OPEN.
393 * On entry, the PARAMETER REGISTER contains a pointer to a
394 * one-field argument block:
395 * - field 1 Contains a handle for an open file.
398 * On exit, the RETURN REGISTER contains:
399 * - 0 if the call is successful
400 * - –1 if the call is not successful.
402 retval
= semihosting_read_fields(target
, 1, fields
);
403 if (retval
!= ERROR_OK
)
406 int fd
= semihosting_get_field(target
, 0, fields
);
407 /* Do not allow to close OpenOCD's own standard streams */
408 if (fd
== 0 || fd
== 1 || fd
== 2) {
409 LOG_DEBUG("ignoring semihosting attempt to close %s",
410 (fd
== 0) ? "stdin" :
411 (fd
== 1) ? "stdout" : "stderr");
412 /* Just pretend success */
413 if (semihosting
->is_fileio
) {
414 semihosting
->result
= 0;
416 semihosting
->result
= 0;
417 semihosting
->sys_errno
= 0;
421 /* Close the descriptor */
422 if (semihosting
->is_fileio
) {
423 semihosting
->hit_fileio
= true;
424 fileio_info
->identifier
= "close";
425 fileio_info
->param_1
= fd
;
427 semihosting
->result
= close(fd
);
428 semihosting
->sys_errno
= errno
;
429 LOG_DEBUG("close(%d)=%d", fd
, (int)semihosting
->result
);
434 case SEMIHOSTING_SYS_ERRNO
: /* 0x13 */
436 * Returns the value of the C library errno variable that is
437 * associated with the semihosting implementation. The errno
438 * variable can be set by a number of C library semihosted
439 * functions, including:
447 * Whether errno is set or not, and to what value, is entirely
448 * host-specific, except where the ISO C standard defines the
452 * There are no parameters. The PARAMETER REGISTER must be 0.
455 * On exit, the RETURN REGISTER contains the value of the C
456 * library errno variable.
458 semihosting
->result
= semihosting
->sys_errno
;
461 case SEMIHOSTING_SYS_EXIT
: /* 0x18 */
463 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
464 * previous versions of the documentation.
466 * An application calls this operation to report an exception
467 * to the debugger directly. The most common use is to report
468 * that execution has completed, using ADP_Stopped_ApplicationExit.
470 * Note: This semihosting operation provides no means for 32-bit
471 * callers to indicate an application exit with a specified exit
472 * code. Semihosting callers may prefer to check for the presence
473 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
474 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
478 * On entry, the PARAMETER register is set to a reason code
479 * describing the cause of the trap. Not all semihosting client
480 * implementations will necessarily trap every corresponding
481 * event. Important reason codes are:
483 * - ADP_Stopped_ApplicationExit 0x20026
484 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
487 * On entry, the PARAMETER REGISTER contains a pointer to a
488 * two-field argument block:
489 * - field 1 The exception type, which is one of the set of
490 * reason codes in the above tables.
491 * - field 2 A subcode, whose meaning depends on the reason
493 * In particular, if field 1 is ADP_Stopped_ApplicationExit
494 * then field 2 is an exit status code, as passed to the C
495 * standard library exit() function. A simulator receiving
496 * this request must notify a connected debugger, if present,
497 * and then exit with the specified status.
500 * No return is expected from these calls. However, it is
501 * possible for the debugger to request that the application
502 * continues by performing an RDI_Execute request or equivalent.
503 * In this case, execution continues with the registers as they
504 * were on entry to the operation, or as subsequently modified
507 if (semihosting
->word_size_bytes
== 8) {
508 retval
= semihosting_read_fields(target
, 2, fields
);
509 if (retval
!= ERROR_OK
)
512 int type
= semihosting_get_field(target
, 0, fields
);
513 int code
= semihosting_get_field(target
, 1, fields
);
515 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
516 if (!gdb_actual_connections
)
520 "semihosting: *** application exited with %d ***\n",
525 "semihosting: application exception %#x\n",
530 if (semihosting
->param
== ADP_STOPPED_APPLICATION_EXIT
) {
531 if (!gdb_actual_connections
)
535 "semihosting: *** application exited normally ***\n");
537 } else if (semihosting
->param
== ADP_STOPPED_RUN_TIME_ERROR
) {
538 /* Chosen more or less arbitrarily to have a nicer message,
539 * otherwise all other return the same exit code 1. */
540 if (!gdb_actual_connections
)
544 "semihosting: *** application exited with error ***\n");
547 if (!gdb_actual_connections
)
551 "semihosting: application exception %#x\n",
552 (unsigned) semihosting
->param
);
556 if (!semihosting
->has_resumable_exit
) {
557 semihosting
->is_resumable
= false;
558 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
562 case SEMIHOSTING_SYS_EXIT_EXTENDED
: /* 0x20 */
564 * This operation is only supported if the semihosting extension
565 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
566 * reported using feature byte 0, bit 0. If this extension is
567 * supported, then the implementation provides a means to
568 * report a normal exit with a nonzero exit status in both 32-bit
569 * and 64-bit semihosting APIs.
571 * The implementation must provide the semihosting call
572 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
574 * SYS_EXIT_EXTENDED is used by an application to report an
575 * exception or exit to the debugger directly. The most common
576 * use is to report that execution has completed, using
577 * ADP_Stopped_ApplicationExit.
580 * On entry, the PARAMETER REGISTER contains a pointer to a
581 * two-field argument block:
582 * - field 1 The exception type, which should be one of the set
583 * of reason codes that are documented for the SYS_EXIT
584 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
585 * - field 2 A subcode, whose meaning depends on the reason
586 * code in field 1. In particular, if field 1 is
587 * ADP_Stopped_ApplicationExit then field 2 is an exit status
588 * code, as passed to the C standard library exit() function.
589 * A simulator receiving this request must notify a connected
590 * debugger, if present, and then exit with the specified status.
593 * No return is expected from these calls.
595 * For the A64 API, this call is identical to the behavior of
596 * the mandatory SYS_EXIT (0x18) call. If this extension is
597 * supported, then both calls must be implemented.
599 retval
= semihosting_read_fields(target
, 2, fields
);
600 if (retval
!= ERROR_OK
)
603 int type
= semihosting_get_field(target
, 0, fields
);
604 int code
= semihosting_get_field(target
, 1, fields
);
606 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
607 if (!gdb_actual_connections
)
611 "semihosting: *** application exited with %d ***\n",
615 fprintf(stderr
, "semihosting: exception %#x\n",
619 if (!semihosting
->has_resumable_exit
) {
620 semihosting
->is_resumable
= false;
621 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
625 case SEMIHOSTING_SYS_FLEN
: /* 0x0C */
627 * Returns the length of a specified file.
630 * On entry, the PARAMETER REGISTER contains a pointer to a
631 * one-field argument block:
632 * - field 1 A handle for a previously opened, seekable file
636 * On exit, the RETURN REGISTER contains:
637 * - The current length of the file object, if the call is
639 * - –1 if an error occurs.
641 if (semihosting
->is_fileio
) {
642 semihosting
->result
= -1;
643 semihosting
->sys_errno
= EINVAL
;
645 retval
= semihosting_read_fields(target
, 1, fields
);
646 if (retval
!= ERROR_OK
)
649 int fd
= semihosting_get_field(target
, 0, fields
);
651 semihosting
->result
= fstat(fd
, &buf
);
652 if (semihosting
->result
== -1) {
653 semihosting
->sys_errno
= errno
;
654 LOG_DEBUG("fstat(%d)=%d", fd
, (int)semihosting
->result
);
657 LOG_DEBUG("fstat(%d)=%d", fd
, (int)semihosting
->result
);
658 semihosting
->result
= buf
.st_size
;
662 case SEMIHOSTING_SYS_GET_CMDLINE
: /* 0x15 */
664 * Returns the command line that is used for the call to the
665 * executable, that is, argc and argv.
668 * On entry, the PARAMETER REGISTER points to a two-field data
669 * block to be used for returning the command string and its length:
670 * - field 1 A pointer to a buffer of at least the size that is
671 * specified in field 2.
672 * - field 2 The length of the buffer in bytes.
676 * If the call is successful, then the RETURN REGISTER contains 0,
677 * the PARAMETER REGISTER is unchanged, and the data block is
678 * updated as follows:
679 * - field 1 A pointer to a null-terminated string of the command
681 * - field 2 The length of the string in bytes.
682 * If the call is not successful, then the RETURN REGISTER
685 * Note: The semihosting implementation might impose limits on
686 * the maximum length of the string that can be transferred.
687 * However, the implementation must be able to support a
688 * command-line length of at least 80 bytes.
690 retval
= semihosting_read_fields(target
, 2, fields
);
691 if (retval
!= ERROR_OK
)
694 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
695 size_t size
= semihosting_get_field(target
, 1, fields
);
697 char *arg
= semihosting
->cmdline
?
698 semihosting
->cmdline
: "";
699 uint32_t len
= strlen(arg
) + 1;
701 semihosting
->result
= -1;
703 semihosting_set_field(target
, len
, 1, fields
);
704 retval
= target_write_buffer(target
, addr
, len
,
706 if (retval
!= ERROR_OK
)
708 semihosting
->result
= 0;
710 retval
= semihosting_write_fields(target
, 2, fields
);
711 if (retval
!= ERROR_OK
)
714 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg
,
715 (int)semihosting
->result
);
719 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
721 * Returns the system stack and heap parameters.
724 * On entry, the PARAMETER REGISTER contains the address of a
725 * pointer to a four-field data block. The contents of the data
726 * block are filled by the function. The following C-like
727 * pseudocode describes the layout of the block:
736 * On exit, the PARAMETER REGISTER is unchanged and the data
737 * block has been updated.
739 retval
= semihosting_read_fields(target
, 1, fields
);
740 if (retval
!= ERROR_OK
)
743 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
744 /* tell the remote we have no idea */
745 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
746 retval
= target_write_memory(target
, addr
, 4,
747 semihosting
->word_size_bytes
,
749 if (retval
!= ERROR_OK
)
751 semihosting
->result
= 0;
755 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
757 * Determines whether the return code from another semihosting
758 * call is an error status or not.
760 * This call is passed a parameter block containing the error
764 * On entry, the PARAMETER REGISTER contains a pointer to a
765 * one-field data block:
766 * - field 1 The required status word to check.
769 * On exit, the RETURN REGISTER contains:
770 * - 0 if the status field is not an error indication
771 * - A nonzero value if the status field is an error indication.
773 retval
= semihosting_read_fields(target
, 1, fields
);
774 if (retval
!= ERROR_OK
)
777 uint64_t code
= semihosting_get_field(target
, 0, fields
);
778 semihosting
->result
= (code
!= 0);
781 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
783 * Checks whether a file is connected to an interactive device.
786 * On entry, the PARAMETER REGISTER contains a pointer to a
787 * one-field argument block:
788 * field 1 A handle for a previously opened file object.
791 * On exit, the RETURN REGISTER contains:
792 * - 1 if the handle identifies an interactive device.
793 * - 0 if the handle identifies a file.
794 * - A value other than 1 or 0 if an error occurs.
796 if (semihosting
->is_fileio
) {
797 semihosting
->hit_fileio
= true;
798 fileio_info
->identifier
= "isatty";
799 fileio_info
->param_1
= semihosting
->param
;
801 retval
= semihosting_read_fields(target
, 1, fields
);
802 if (retval
!= ERROR_OK
)
804 int fd
= semihosting_get_field(target
, 0, fields
);
805 semihosting
->result
= isatty(fd
);
806 semihosting
->sys_errno
= errno
;
807 LOG_DEBUG("isatty(%d)=%d", fd
, (int)semihosting
->result
);
811 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
813 * Opens a file on the host system.
815 * The file path is specified either as relative to the current
816 * directory of the host process, or absolute, using the path
817 * conventions of the host operating system.
819 * Semihosting implementations must support opening the special
820 * path name :semihosting-features as part of the semihosting
821 * extensions reporting mechanism.
823 * ARM targets interpret the special path name :tt as meaning
824 * the console input stream, for an open-read or the console
825 * output stream, for an open-write. Opening these streams is
826 * performed as part of the standard startup code for those
827 * applications that reference the C stdio streams. The
828 * semihosting extension SH_EXT_STDOUT_STDERR allows the
829 * semihosting caller to open separate output streams
830 * corresponding to stdout and stderr. This extension is
831 * reported using feature byte 0, bit 1. Use SYS_OPEN with
832 * the special path name :semihosting-features to access the
835 * If this extension is supported, the implementation must
836 * support the following additional semantics to SYS_OPEN:
837 * - If the special path name :tt is opened with an fopen
838 * mode requesting write access (w, wb, w+, or w+b), then
839 * this is a request to open stdout.
840 * - If the special path name :tt is opened with a mode
841 * requesting append access (a, ab, a+, or a+b), then this is
842 * a request to open stderr.
845 * On entry, the PARAMETER REGISTER contains a pointer to a
846 * three-field argument block:
847 * - field 1 A pointer to a null-terminated string containing
848 * a file or device name.
849 * - field 2 An integer that specifies the file opening mode.
850 * - field 3 An integer that gives the length of the string
851 * pointed to by field 1.
853 * The length does not include the terminating null character
854 * that must be present.
857 * On exit, the RETURN REGISTER contains:
858 * - A nonzero handle if the call is successful.
859 * - –1 if the call is not successful.
861 retval
= semihosting_read_fields(target
, 3, fields
);
862 if (retval
!= ERROR_OK
)
865 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
866 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
867 size_t len
= semihosting_get_field(target
, 2, fields
);
870 semihosting
->result
= -1;
871 semihosting
->sys_errno
= EINVAL
;
874 size_t basedir_len
= semihosting
->basedir
? strlen(semihosting
->basedir
) : 0;
875 uint8_t *fn
= malloc(basedir_len
+ len
+ 2);
877 semihosting
->result
= -1;
878 semihosting
->sys_errno
= ENOMEM
;
880 if (basedir_len
> 0) {
881 strcpy((char *)fn
, semihosting
->basedir
);
882 if (fn
[basedir_len
- 1] != '/')
883 fn
[basedir_len
++] = '/';
885 retval
= target_read_memory(target
, addr
, 1, len
, fn
+ basedir_len
);
886 if (retval
!= ERROR_OK
) {
890 fn
[basedir_len
+ len
] = 0;
891 /* TODO: implement the :semihosting-features special file.
893 if (semihosting
->is_fileio
) {
894 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
895 semihosting
->result
= -1;
896 semihosting
->sys_errno
= EINVAL
;
897 } else if (strcmp((char *)fn
, ":tt") == 0) {
899 semihosting
->result
= 0;
901 semihosting
->result
= 1;
903 semihosting
->result
= 2;
905 semihosting
->result
= -1;
907 semihosting
->hit_fileio
= true;
908 fileio_info
->identifier
= "open";
909 fileio_info
->param_1
= addr
;
910 fileio_info
->param_2
= len
;
911 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
912 fileio_info
->param_4
= 0644;
915 if (strcmp((char *)fn
, ":tt") == 0) {
917 * - 0-3 ("r") for stdin,
918 * - 4-7 ("w") for stdout,
919 * - 8-11 ("a") for stderr */
921 int fd
= dup(STDIN_FILENO
);
922 semihosting
->result
= fd
;
923 semihosting
->stdin_fd
= fd
;
924 semihosting
->sys_errno
= errno
;
925 LOG_DEBUG("dup(STDIN)=%d",
926 (int)semihosting
->result
);
927 } else if (mode
< 8) {
928 int fd
= dup(STDOUT_FILENO
);
929 semihosting
->result
= fd
;
930 semihosting
->stdout_fd
= fd
;
931 semihosting
->sys_errno
= errno
;
932 LOG_DEBUG("dup(STDOUT)=%d",
933 (int)semihosting
->result
);
935 int fd
= dup(STDERR_FILENO
);
936 semihosting
->result
= fd
;
937 semihosting
->stderr_fd
= fd
;
938 semihosting
->sys_errno
= errno
;
939 LOG_DEBUG("dup(STDERR)=%d",
940 (int)semihosting
->result
);
943 /* cygwin requires the permission setting
944 * otherwise it will fail to reopen a previously
946 semihosting
->result
= open((char *)fn
,
947 open_host_modeflags
[mode
],
949 semihosting
->sys_errno
= errno
;
950 LOG_DEBUG("open('%s')=%d", fn
,
951 (int)semihosting
->result
);
959 case SEMIHOSTING_SYS_READ
: /* 0x06 */
961 * Reads the contents of a file into a buffer. The file position
962 * is specified either:
963 * - Explicitly by a SYS_SEEK.
964 * - Implicitly one byte beyond the previous SYS_READ or
967 * The file position is at the start of the file when it is
968 * opened, and is lost when the file is closed. Perform the
969 * file operation as a single action whenever possible. For
970 * example, do not split a read of 16KB into four 4KB chunks
971 * unless there is no alternative.
974 * On entry, the PARAMETER REGISTER contains a pointer to a
975 * three-field data block:
976 * - field 1 Contains a handle for a file previously opened
978 * - field 2 Points to a buffer.
979 * - field 3 Contains the number of bytes to read to the buffer
983 * On exit, the RETURN REGISTER contains the number of bytes not
984 * filled in the buffer (buffer_length - bytes_read) as follows:
985 * - If the RETURN REGISTER is 0, the entire buffer was
986 * successfully filled.
987 * - If the RETURN REGISTER is the same as field 3, no bytes
988 * were read (EOF can be assumed).
989 * - If the RETURN REGISTER contains a value smaller than
990 * field 3, the read succeeded but the buffer was only partly
991 * filled. For interactive devices, this is the most common
994 retval
= semihosting_read_fields(target
, 3, fields
);
995 if (retval
!= ERROR_OK
)
998 int fd
= semihosting_get_field(target
, 0, fields
);
999 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1000 size_t len
= semihosting_get_field(target
, 2, fields
);
1001 if (semihosting
->is_fileio
) {
1002 semihosting
->hit_fileio
= true;
1003 fileio_info
->identifier
= "read";
1004 fileio_info
->param_1
= fd
;
1005 fileio_info
->param_2
= addr
;
1006 fileio_info
->param_3
= len
;
1008 uint8_t *buf
= malloc(len
);
1010 semihosting
->result
= -1;
1011 semihosting
->sys_errno
= ENOMEM
;
1013 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
1014 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%d",
1018 (int)semihosting
->result
);
1019 if (semihosting
->result
>= 0) {
1020 retval
= target_write_buffer(target
, addr
,
1021 semihosting
->result
,
1023 if (retval
!= ERROR_OK
) {
1027 /* the number of bytes NOT filled in */
1028 semihosting
->result
= len
-
1029 semihosting
->result
;
1037 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1039 * Reads a byte from the console.
1042 * The PARAMETER REGISTER must contain 0. There are no other
1043 * parameters or values possible.
1046 * On exit, the RETURN REGISTER contains the byte read from
1049 if (semihosting
->is_fileio
) {
1050 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1053 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1054 LOG_DEBUG("getchar()=%d", (int)semihosting
->result
);
1057 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1059 * Deletes a specified file on the host filing system.
1062 * On entry, the PARAMETER REGISTER contains a pointer to a
1063 * two-field argument block:
1064 * - field 1 Points to a null-terminated string that gives the
1065 * path name of the file to be deleted.
1066 * - field 2 The length of the string.
1069 * On exit, the RETURN REGISTER contains:
1070 * - 0 if the delete is successful
1071 * - A nonzero, host-specific error code if the delete fails.
1073 retval
= semihosting_read_fields(target
, 2, fields
);
1074 if (retval
!= ERROR_OK
)
1077 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1078 size_t len
= semihosting_get_field(target
, 1, fields
);
1079 if (semihosting
->is_fileio
) {
1080 semihosting
->hit_fileio
= true;
1081 fileio_info
->identifier
= "unlink";
1082 fileio_info
->param_1
= addr
;
1083 fileio_info
->param_2
= len
;
1085 uint8_t *fn
= malloc(len
+1);
1087 semihosting
->result
= -1;
1088 semihosting
->sys_errno
= ENOMEM
;
1091 target_read_memory(target
, addr
, 1, len
,
1093 if (retval
!= ERROR_OK
) {
1098 semihosting
->result
= remove((char *)fn
);
1099 semihosting
->sys_errno
= errno
;
1100 LOG_DEBUG("remove('%s')=%d", fn
,
1101 (int)semihosting
->result
);
1109 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1111 * Renames a specified file.
1114 * On entry, the PARAMETER REGISTER contains a pointer to a
1115 * four-field data block:
1116 * - field 1 A pointer to the name of the old file.
1117 * - field 2 The length of the old filename.
1118 * - field 3 A pointer to the new filename.
1119 * - field 4 The length of the new filename. Both strings are
1123 * On exit, the RETURN REGISTER contains:
1124 * - 0 if the rename is successful.
1125 * - A nonzero, host-specific error code if the rename fails.
1127 retval
= semihosting_read_fields(target
, 4, fields
);
1128 if (retval
!= ERROR_OK
)
1131 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1132 size_t len1
= semihosting_get_field(target
, 1, fields
);
1133 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1134 size_t len2
= semihosting_get_field(target
, 3, fields
);
1135 if (semihosting
->is_fileio
) {
1136 semihosting
->hit_fileio
= true;
1137 fileio_info
->identifier
= "rename";
1138 fileio_info
->param_1
= addr1
;
1139 fileio_info
->param_2
= len1
;
1140 fileio_info
->param_3
= addr2
;
1141 fileio_info
->param_4
= len2
;
1143 uint8_t *fn1
= malloc(len1
+1);
1144 uint8_t *fn2
= malloc(len2
+1);
1148 semihosting
->result
= -1;
1149 semihosting
->sys_errno
= ENOMEM
;
1151 retval
= target_read_memory(target
, addr1
, 1, len1
,
1153 if (retval
!= ERROR_OK
) {
1158 retval
= target_read_memory(target
, addr2
, 1, len2
,
1160 if (retval
!= ERROR_OK
) {
1167 semihosting
->result
= rename((char *)fn1
,
1169 semihosting
->sys_errno
= errno
;
1170 LOG_DEBUG("rename('%s', '%s')=%d", fn1
, fn2
,
1171 (int)semihosting
->result
);
1180 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1182 * Seeks to a specified position in a file using an offset
1183 * specified from the start of the file. The file is assumed
1184 * to be a byte array and the offset is given in bytes.
1187 * On entry, the PARAMETER REGISTER contains a pointer to a
1188 * two-field data block:
1189 * - field 1 A handle for a seekable file object.
1190 * - field 2 The absolute byte position to seek to.
1193 * On exit, the RETURN REGISTER contains:
1194 * - 0 if the request is successful.
1195 * - A negative value if the request is not successful.
1196 * Use SYS_ERRNO to read the value of the host errno variable
1197 * describing the error.
1199 * Note: The effect of seeking outside the current extent of
1200 * the file object is undefined.
1202 retval
= semihosting_read_fields(target
, 2, fields
);
1203 if (retval
!= ERROR_OK
)
1206 int fd
= semihosting_get_field(target
, 0, fields
);
1207 off_t pos
= semihosting_get_field(target
, 1, fields
);
1208 if (semihosting
->is_fileio
) {
1209 semihosting
->hit_fileio
= true;
1210 fileio_info
->identifier
= "lseek";
1211 fileio_info
->param_1
= fd
;
1212 fileio_info
->param_2
= pos
;
1213 fileio_info
->param_3
= SEEK_SET
;
1215 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1216 semihosting
->sys_errno
= errno
;
1217 LOG_DEBUG("lseek(%d, %d)=%d", fd
, (int)pos
,
1218 (int)semihosting
->result
);
1219 if (semihosting
->result
== pos
)
1220 semihosting
->result
= 0;
1225 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1227 * Passes a command to the host command-line interpreter.
1228 * This enables you to execute a system command such as dir,
1229 * ls, or pwd. The terminal I/O is on the host, and is not
1230 * visible to the target.
1233 * On entry, the PARAMETER REGISTER contains a pointer to a
1234 * two-field argument block:
1235 * - field 1 Points to a string to be passed to the host
1236 * command-line interpreter.
1237 * - field 2 The length of the string.
1240 * On exit, the RETURN REGISTER contains the return status.
1243 /* Provide SYS_SYSTEM functionality. Uses the
1244 * libc system command, there may be a reason *NOT*
1245 * to use this, but as I can't think of one, I
1246 * implemented it this way.
1248 retval
= semihosting_read_fields(target
, 2, fields
);
1249 if (retval
!= ERROR_OK
)
1252 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1253 size_t len
= semihosting_get_field(target
, 1, fields
);
1254 if (semihosting
->is_fileio
) {
1255 semihosting
->hit_fileio
= true;
1256 fileio_info
->identifier
= "system";
1257 fileio_info
->param_1
= addr
;
1258 fileio_info
->param_2
= len
;
1260 uint8_t *cmd
= malloc(len
+1);
1262 semihosting
->result
= -1;
1263 semihosting
->sys_errno
= ENOMEM
;
1265 retval
= target_read_memory(target
,
1270 if (retval
!= ERROR_OK
) {
1275 semihosting
->result
= system(
1277 LOG_DEBUG("system('%s')=%d",
1279 (int)semihosting
->result
);
1288 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1290 * Returns the number of seconds since 00:00 January 1, 1970.
1291 * This value is real-world time, regardless of any debug agent
1295 * There are no parameters.
1298 * On exit, the RETURN REGISTER contains the number of seconds.
1300 semihosting
->result
= time(NULL
);
1303 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1305 * Writes the contents of a buffer to a specified file at the
1306 * current file position. The file position is specified either:
1307 * - Explicitly, by a SYS_SEEK.
1308 * - Implicitly as one byte beyond the previous SYS_READ or
1309 * SYS_WRITE request.
1311 * The file position is at the start of the file when the file
1312 * is opened, and is lost when the file is closed.
1314 * Perform the file operation as a single action whenever
1315 * possible. For example, do not split a write of 16KB into
1316 * four 4KB chunks unless there is no alternative.
1319 * On entry, the PARAMETER REGISTER contains a pointer to a
1320 * three-field data block:
1321 * - field 1 Contains a handle for a file previously opened
1323 * - field 2 Points to the memory containing the data to be written.
1324 * - field 3 Contains the number of bytes to be written from
1325 * the buffer to the file.
1328 * On exit, the RETURN REGISTER contains:
1329 * - 0 if the call is successful.
1330 * - The number of bytes that are not written, if there is an error.
1332 retval
= semihosting_read_fields(target
, 3, fields
);
1333 if (retval
!= ERROR_OK
)
1336 int fd
= semihosting_get_field(target
, 0, fields
);
1337 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1338 size_t len
= semihosting_get_field(target
, 2, fields
);
1339 if (semihosting
->is_fileio
) {
1340 semihosting
->hit_fileio
= true;
1341 fileio_info
->identifier
= "write";
1342 fileio_info
->param_1
= fd
;
1343 fileio_info
->param_2
= addr
;
1344 fileio_info
->param_3
= len
;
1346 uint8_t *buf
= malloc(len
);
1348 semihosting
->result
= -1;
1349 semihosting
->sys_errno
= ENOMEM
;
1351 retval
= target_read_buffer(target
, addr
, len
, buf
);
1352 if (retval
!= ERROR_OK
) {
1356 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1357 semihosting
->sys_errno
= errno
;
1358 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%d",
1362 (int)semihosting
->result
);
1363 if (semihosting
->result
>= 0) {
1364 /* The number of bytes that are NOT written.
1366 semihosting
->result
= len
-
1367 semihosting
->result
;
1376 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1378 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1379 * to the debug channel. When executed under a semihosting
1380 * debugger, the character appears on the host debugger console.
1383 * On entry, the PARAMETER REGISTER contains a pointer to the
1387 * None. The RETURN REGISTER is corrupted.
1389 if (semihosting
->is_fileio
) {
1390 semihosting
->hit_fileio
= true;
1391 fileio_info
->identifier
= "write";
1392 fileio_info
->param_1
= 1;
1393 fileio_info
->param_2
= semihosting
->param
;
1394 fileio_info
->param_3
= 1;
1396 uint64_t addr
= semihosting
->param
;
1398 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1399 if (retval
!= ERROR_OK
)
1401 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1402 semihosting
->result
= 0;
1406 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1408 * Writes a null-terminated string to the debug channel.
1409 * When executed under a semihosting debugger, the characters
1410 * appear on the host debugger console.
1413 * On entry, the PARAMETER REGISTER contains a pointer to the
1414 * first byte of the string.
1417 * None. The RETURN REGISTER is corrupted.
1419 if (semihosting
->is_fileio
) {
1421 uint64_t addr
= semihosting
->param
;
1424 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1425 if (retval
!= ERROR_OK
)
1431 semihosting
->hit_fileio
= true;
1432 fileio_info
->identifier
= "write";
1433 fileio_info
->param_1
= 1;
1434 fileio_info
->param_2
= semihosting
->param
;
1435 fileio_info
->param_3
= count
;
1437 uint64_t addr
= semihosting
->param
;
1440 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1441 if (retval
!= ERROR_OK
)
1445 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1447 semihosting
->result
= 0;
1451 case SEMIHOSTING_USER_CMD_0x100
... SEMIHOSTING_USER_CMD_0x107
:
1453 * This is a user defined operation (while user cmds 0x100-0x1ff
1454 * are possible, only 0x100-0x107 are currently implemented).
1456 * Reads the user operation parameters from target, then fires the
1457 * corresponding target event. When the target callbacks returned,
1458 * cleans up the command parameter buffer.
1461 * On entry, the PARAMETER REGISTER contains a pointer to a
1462 * two-field data block:
1463 * - field 1 Contains a pointer to the bound command parameter
1465 * - field 2 Contains the command parameter string length
1468 * On exit, the RETURN REGISTER contains the return status.
1471 assert(!semihosting_user_op_params
);
1473 retval
= semihosting_read_fields(target
, 2, fields
);
1474 if (retval
!= ERROR_OK
) {
1475 LOG_ERROR("Failed to read fields for user defined command"
1476 " op=0x%x", semihosting
->op
);
1480 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1482 size_t len
= semihosting_get_field(target
, 1, fields
);
1483 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1484 LOG_ERROR("The maximum length for user defined command "
1485 "parameter is %u, received length is %zu (op=0x%x)",
1486 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1492 semihosting_user_op_params
= malloc(len
+ 1);
1493 if (!semihosting_user_op_params
)
1495 semihosting_user_op_params
[len
] = 0;
1497 retval
= target_read_buffer(target
, addr
, len
,
1498 (uint8_t *)(semihosting_user_op_params
));
1499 if (retval
!= ERROR_OK
) {
1500 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1502 free(semihosting_user_op_params
);
1503 semihosting_user_op_params
= NULL
;
1507 target_handle_event(target
, semihosting
->op
);
1508 free(semihosting_user_op_params
);
1509 semihosting_user_op_params
= NULL
;
1511 semihosting
->result
= 0;
1516 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1518 * Returns the number of elapsed target ticks since execution
1520 * Use SYS_TICKFREQ to determine the tick frequency.
1523 * On entry, the PARAMETER REGISTER points to a two-field data
1524 * block to be used for returning the number of elapsed ticks:
1525 * - field 1 The least significant field and is at the low address.
1526 * - field 2 The most significant field and is at the high address.
1529 * On entry the PARAMETER REGISTER points to a one-field data
1530 * block to be used for returning the number of elapsed ticks:
1531 * - field 1 The number of elapsed ticks as a 64-bit value.
1535 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1536 * REGISTER is unchanged, and the data block pointed to by the
1537 * PARAMETER REGISTER is filled in with the number of elapsed
1539 * - On failure, the RETURN REGISTER contains -1, and the
1540 * PARAMETER REGISTER contains -1.
1542 * Note: Some semihosting implementations might not support this
1543 * semihosting operation, and they always return -1 in the
1547 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1549 * Returns the tick frequency.
1552 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1555 * On exit, the RETURN REGISTER contains either:
1556 * - The number of ticks per second.
1557 * - –1 if the target does not know the value of one tick.
1559 * Note: Some semihosting implementations might not support
1560 * this semihosting operation, and they always return -1 in the
1564 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1566 * Returns a temporary name for a file identified by a system
1570 * On entry, the PARAMETER REGISTER contains a pointer to a
1571 * three-word argument block:
1572 * - field 1 A pointer to a buffer.
1573 * - field 2 A target identifier for this filename. Its value
1574 * must be an integer in the range 0-255.
1575 * - field 3 Contains the length of the buffer. The length must
1576 * be at least the value of L_tmpnam on the host system.
1579 * On exit, the RETURN REGISTER contains:
1580 * - 0 if the call is successful.
1581 * - –1 if an error occurs.
1583 * The buffer pointed to by the PARAMETER REGISTER contains
1584 * the filename, prefixed with a suitable directory name.
1585 * If you use the same target identifier again, the same
1586 * filename is returned.
1588 * Note: The returned string must be null-terminated.
1592 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1593 (unsigned) semihosting
->op
);
1594 semihosting
->result
= -1;
1595 semihosting
->sys_errno
= ENOTSUP
;
1598 if (!semihosting
->hit_fileio
) {
1599 retval
= semihosting
->post_result(target
);
1600 if (retval
!= ERROR_OK
) {
1601 LOG_ERROR("Failed to post semihosting result");
1609 /* -------------------------------------------------------------------------
1610 * Local functions. */
1612 static int semihosting_common_fileio_info(struct target
*target
,
1613 struct gdb_fileio_info
*fileio_info
)
1615 struct semihosting
*semihosting
= target
->semihosting
;
1620 * To avoid unnecessary duplication, semihosting prepares the
1621 * fileio_info structure out-of-band when the target halts. See
1622 * do_semihosting for more detail.
1624 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1630 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1631 int fileio_errno
, bool ctrl_c
)
1633 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1634 struct semihosting
*semihosting
= target
->semihosting
;
1638 /* clear pending status */
1639 semihosting
->hit_fileio
= false;
1641 semihosting
->result
= result
;
1642 semihosting
->sys_errno
= fileio_errno
;
1645 * Some fileio results do not match up with what the semihosting
1646 * operation expects; for these operations, we munge the results
1649 switch (semihosting
->op
) {
1650 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1652 semihosting
->result
= fileio_info
->param_3
;
1654 semihosting
->result
= 0;
1657 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1658 if (result
== (int)fileio_info
->param_3
)
1659 semihosting
->result
= 0;
1661 semihosting
->result
= fileio_info
->param_3
;
1664 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1666 semihosting
->result
= 0;
1670 return semihosting
->post_result(target
);
1674 * Read all fields of a command from target to buffer.
1676 static int semihosting_read_fields(struct target
*target
, size_t number
,
1679 struct semihosting
*semihosting
= target
->semihosting
;
1680 /* Use 4-byte multiples to trigger fast memory access. */
1681 return target_read_memory(target
, semihosting
->param
, 4,
1682 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1686 * Write all fields of a command from buffer to target.
1688 static int semihosting_write_fields(struct target
*target
, size_t number
,
1691 struct semihosting
*semihosting
= target
->semihosting
;
1692 /* Use 4-byte multiples to trigger fast memory access. */
1693 return target_write_memory(target
, semihosting
->param
, 4,
1694 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1698 * Extract a field from the buffer, considering register size and endianness.
1700 static uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1703 struct semihosting
*semihosting
= target
->semihosting
;
1704 if (semihosting
->word_size_bytes
== 8)
1705 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1707 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1711 * Store a field in the buffer, considering register size and endianness.
1713 static void semihosting_set_field(struct target
*target
, uint64_t value
,
1717 struct semihosting
*semihosting
= target
->semihosting
;
1718 if (semihosting
->word_size_bytes
== 8)
1719 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1721 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1724 /* -------------------------------------------------------------------------
1725 * Semihosting redirect over TCP structs and functions */
1727 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1729 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1730 service
->semihosting
->tcp_connection
= connection
;
1735 static int semihosting_service_input_handler(struct connection
*connection
)
1737 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1739 if (!connection
->input_pending
) {
1740 /* consume received data, not for semihosting IO */
1741 const int buf_len
= 100;
1743 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1745 if (bytes_read
== 0) {
1746 return ERROR_SERVER_REMOTE_CLOSED
;
1747 } else if (bytes_read
== -1) {
1748 LOG_ERROR("error during read: %s", strerror(errno
));
1749 return ERROR_SERVER_REMOTE_CLOSED
;
1751 } else if (service
->error
!= ERROR_OK
) {
1752 return ERROR_SERVER_REMOTE_CLOSED
;
1758 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1760 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1762 free(service
->name
);
1769 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1771 if (!semihosting
->tcp_connection
)
1774 struct service
*service
= semihosting
->tcp_connection
->service
;
1775 remove_service(service
->name
, service
->port
);
1776 semihosting
->tcp_connection
= NULL
;
1780 static const struct service_driver semihosting_service_driver
= {
1781 .name
= "semihosting",
1782 .new_connection_during_keep_alive_handler
= NULL
,
1783 .new_connection_handler
= semihosting_service_new_connection_handler
,
1784 .input_handler
= semihosting_service_input_handler
,
1785 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1786 .keep_client_alive_handler
= NULL
,
1789 /* -------------------------------------------------------------------------
1790 * Common semihosting commands handlers. */
1792 COMMAND_HANDLER(handle_common_semihosting_command
)
1794 struct target
*target
= get_current_target(CMD_CTX
);
1797 LOG_ERROR("No target selected");
1801 struct semihosting
*semihosting
= target
->semihosting
;
1803 command_print(CMD
, "semihosting not supported for current target");
1810 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1812 if (!target_was_examined(target
)) {
1813 LOG_ERROR("Target not examined yet");
1817 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1818 LOG_ERROR("Failed to Configure semihosting");
1822 /* FIXME never let that "catch" be dropped! (???) */
1823 semihosting
->is_active
= is_active
;
1826 command_print(CMD
, "semihosting is %s",
1827 semihosting
->is_active
1828 ? "enabled" : "disabled");
1833 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1835 struct target
*target
= get_current_target(CMD_CTX
);
1837 if (target
== NULL
) {
1838 LOG_ERROR("No target selected");
1842 struct semihosting
*semihosting
= target
->semihosting
;
1844 command_print(CMD
, "semihosting not supported for current target");
1848 if (!semihosting
->is_active
) {
1849 command_print(CMD
, "semihosting not yet enabled for current target");
1853 enum semihosting_redirect_config cfg
;
1857 return ERROR_COMMAND_SYNTAX_ERROR
;
1859 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1860 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1862 return ERROR_COMMAND_SYNTAX_ERROR
;
1863 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1864 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1865 return ERROR_COMMAND_SYNTAX_ERROR
;
1869 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1870 if (CMD_ARGC
== 3) {
1871 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1872 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1873 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1874 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1875 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1876 return ERROR_COMMAND_SYNTAX_ERROR
;
1879 return ERROR_COMMAND_SYNTAX_ERROR
;
1882 semihosting_tcp_close_cnx(semihosting
);
1883 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1885 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1886 struct semihosting_tcp_service
*service
=
1887 calloc(1, sizeof(struct semihosting_tcp_service
));
1889 LOG_ERROR("Failed to allocate semihosting TCP service.");
1893 service
->semihosting
= semihosting
;
1895 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1896 if (!service
->name
) {
1897 LOG_ERROR("Out of memory");
1902 int ret
= add_service(&semihosting_service_driver
,
1905 if (ret
!= ERROR_OK
) {
1906 LOG_ERROR("failed to initialize %s", service
->name
);
1907 free(service
->name
);
1913 semihosting
->redirect_cfg
= cfg
;
1918 COMMAND_HANDLER(handle_common_semihosting_fileio_command
)
1920 struct target
*target
= get_current_target(CMD_CTX
);
1923 LOG_ERROR("No target selected");
1927 struct semihosting
*semihosting
= target
->semihosting
;
1929 command_print(CMD
, "semihosting not supported for current target");
1933 if (!semihosting
->is_active
) {
1934 command_print(CMD
, "semihosting not yet enabled for current target");
1939 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->is_fileio
);
1941 command_print(CMD
, "semihosting fileio is %s",
1942 semihosting
->is_fileio
1943 ? "enabled" : "disabled");
1948 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1950 struct target
*target
= get_current_target(CMD_CTX
);
1954 LOG_ERROR("No target selected");
1958 struct semihosting
*semihosting
= target
->semihosting
;
1960 command_print(CMD
, "semihosting not supported for current target");
1964 free(semihosting
->cmdline
);
1965 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
1967 for (i
= 1; i
< CMD_ARGC
; i
++) {
1968 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
1971 free(semihosting
->cmdline
);
1972 semihosting
->cmdline
= cmdline
;
1975 command_print(CMD
, "semihosting command line is [%s]",
1976 semihosting
->cmdline
);
1981 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
1983 struct target
*target
= get_current_target(CMD_CTX
);
1986 LOG_ERROR("No target selected");
1990 struct semihosting
*semihosting
= target
->semihosting
;
1992 command_print(CMD
, "semihosting not supported for current target");
1996 if (!semihosting
->is_active
) {
1997 command_print(CMD
, "semihosting not yet enabled for current target");
2002 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
2004 command_print(CMD
, "semihosting resumable exit is %s",
2005 semihosting
->has_resumable_exit
2006 ? "enabled" : "disabled");
2011 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
2013 struct target
*target
= get_current_target(CMD_CTX
);
2014 struct semihosting
*semihosting
= target
->semihosting
;
2017 return ERROR_COMMAND_SYNTAX_ERROR
;
2019 if (!semihosting
->is_active
) {
2020 LOG_ERROR("semihosting not yet enabled for current target");
2024 if (!semihosting_user_op_params
) {
2025 LOG_ERROR("This command is usable only from a registered user "
2026 "semihosting event callback.");
2030 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2035 COMMAND_HANDLER(handle_common_semihosting_basedir_command
)
2037 struct target
*target
= get_current_target(CMD_CTX
);
2040 return ERROR_COMMAND_SYNTAX_ERROR
;
2043 LOG_ERROR("No target selected");
2047 struct semihosting
*semihosting
= target
->semihosting
;
2049 command_print(CMD
, "semihosting not supported for current target");
2053 if (!semihosting
->is_active
) {
2054 command_print(CMD
, "semihosting not yet enabled for current target");
2059 free(semihosting
->basedir
);
2060 semihosting
->basedir
= strdup(CMD_ARGV
[0]);
2061 if (!semihosting
->basedir
) {
2062 command_print(CMD
, "semihosting failed to allocate memory for basedir!");
2067 command_print(CMD
, "semihosting base dir: %s",
2068 semihosting
->basedir
? semihosting
->basedir
: "");
2073 const struct command_registration semihosting_common_handlers
[] = {
2075 .name
= "semihosting",
2076 .handler
= handle_common_semihosting_command
,
2077 .mode
= COMMAND_EXEC
,
2078 .usage
= "['enable'|'disable']",
2079 .help
= "activate support for semihosting operations",
2082 .name
= "semihosting_redirect",
2083 .handler
= handle_common_semihosting_redirect_command
,
2084 .mode
= COMMAND_EXEC
,
2085 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2086 .help
= "redirect semihosting IO",
2089 .name
= "semihosting_cmdline",
2090 .handler
= handle_common_semihosting_cmdline
,
2091 .mode
= COMMAND_EXEC
,
2092 .usage
= "arguments",
2093 .help
= "command line arguments to be passed to program",
2096 .name
= "semihosting_fileio",
2097 .handler
= handle_common_semihosting_fileio_command
,
2098 .mode
= COMMAND_EXEC
,
2099 .usage
= "['enable'|'disable']",
2100 .help
= "activate support for semihosting fileio operations",
2103 .name
= "semihosting_resexit",
2104 .handler
= handle_common_semihosting_resumable_exit_command
,
2105 .mode
= COMMAND_EXEC
,
2106 .usage
= "['enable'|'disable']",
2107 .help
= "activate support for semihosting resumable exit",
2110 .name
= "semihosting_read_user_param",
2111 .handler
= handle_common_semihosting_read_user_param_command
,
2112 .mode
= COMMAND_EXEC
,
2114 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2117 .name
= "semihosting_basedir",
2118 .handler
= handle_common_semihosting_basedir_command
,
2119 .mode
= COMMAND_EXEC
,
2121 .help
= "set the base directory for semihosting I/O operations",
2123 COMMAND_REGISTRATION_DONE