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
;
163 /* If possible, update it in setup(). */
164 semihosting
->setup_time
= clock();
166 semihosting
->setup
= setup
;
167 semihosting
->post_result
= post_result
;
169 target
->semihosting
= semihosting
;
171 target
->type
->get_gdb_fileio_info
= semihosting_common_fileio_info
;
172 target
->type
->gdb_fileio_end
= semihosting_common_fileio_end
;
177 struct semihosting_tcp_service
{
178 struct semihosting
*semihosting
;
183 static bool semihosting_is_redirected(struct semihosting
*semihosting
, int fd
)
185 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_NONE
)
188 bool is_read_op
= false;
190 switch (semihosting
->op
) {
191 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
192 case SEMIHOSTING_SYS_READC
:
195 case SEMIHOSTING_SYS_WRITEC
:
196 case SEMIHOSTING_SYS_WRITE0
:
197 /* debug operations are redirected when CFG is either DEBUG or ALL */
198 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_STDIO
)
202 /* check stdio semihosting operations: READ and WRITE */
203 case SEMIHOSTING_SYS_READ
:
206 case SEMIHOSTING_SYS_WRITE
:
207 /* stdio operations are redirected when CFG is either STDIO or ALL */
208 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_DEBUG
)
217 return fd
== semihosting
->stdin_fd
;
219 /* write operation */
220 return fd
== semihosting
->stdout_fd
|| fd
== semihosting
->stderr_fd
;
223 static ssize_t
semihosting_redirect_write(struct semihosting
*semihosting
, void *buf
, int size
)
225 if (!semihosting
->tcp_connection
) {
226 LOG_ERROR("No connected TCP client for semihosting");
227 semihosting
->sys_errno
= EBADF
; /* Bad file number */
231 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
233 int retval
= connection_write(semihosting
->tcp_connection
, buf
, size
);
236 log_socket_error(service
->name
);
241 static ssize_t
semihosting_write(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
243 if (semihosting_is_redirected(semihosting
, fd
))
244 return semihosting_redirect_write(semihosting
, buf
, size
);
247 return write(fd
, buf
, size
);
250 static ssize_t
semihosting_redirect_read(struct semihosting
*semihosting
, void *buf
, int size
)
252 if (!semihosting
->tcp_connection
) {
253 LOG_ERROR("No connected TCP client for semihosting");
254 semihosting
->sys_errno
= EBADF
; /* Bad file number */
258 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
260 service
->error
= ERROR_OK
;
261 semihosting
->tcp_connection
->input_pending
= true;
263 int retval
= connection_read(semihosting
->tcp_connection
, buf
, size
);
266 service
->error
= ERROR_SERVER_REMOTE_CLOSED
;
269 log_socket_error(service
->name
);
271 semihosting
->tcp_connection
->input_pending
= false;
276 static inline int semihosting_putchar(struct semihosting
*semihosting
, int fd
, int c
)
278 if (semihosting_is_redirected(semihosting
, fd
))
279 return semihosting_redirect_write(semihosting
, &c
, 1);
281 /* default putchar */
285 static inline ssize_t
semihosting_read(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
287 if (semihosting_is_redirected(semihosting
, fd
))
288 return semihosting_redirect_read(semihosting
, buf
, size
);
291 ssize_t result
= read(fd
, buf
, size
);
292 semihosting
->sys_errno
= errno
;
297 static inline int semihosting_getchar(struct semihosting
*semihosting
, int fd
)
299 if (semihosting_is_redirected(semihosting
, fd
)) {
302 if (semihosting_redirect_read(semihosting
, &c
, 1) > 0)
308 /* default getchar */
313 * User operation parameter string storage buffer. Contains valid data when the
314 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
316 static char *semihosting_user_op_params
;
319 * Portable implementation of ARM semihosting calls.
320 * Performs the currently pending semihosting operation
321 * encoded in target->semihosting.
323 int semihosting_common(struct target
*target
)
325 struct semihosting
*semihosting
= target
->semihosting
;
327 /* Silently ignore if the semihosting field was not set. */
331 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
334 * By default return an error.
335 * The actual result must be set by each function
337 semihosting
->result
= -1;
339 /* Most operations are resumable, except the two exit calls. */
340 semihosting
->is_resumable
= true;
344 /* Enough space to hold 4 long words. */
347 LOG_DEBUG("op=0x%x, param=0x%" PRIx64
, semihosting
->op
,
350 switch (semihosting
->op
) {
352 case SEMIHOSTING_SYS_CLOCK
: /* 0x10 */
354 * Returns the number of centiseconds (hundredths of a second)
355 * since the execution started.
357 * Values returned can be of limited use for some benchmarking
358 * purposes because of communication overhead or other
359 * agent-specific factors. For example, with a debug hardware
360 * unit the request is passed back to the host for execution.
361 * This can lead to unpredictable delays in transmission and
362 * process scheduling.
364 * Use this function to calculate time intervals, by calculating
365 * differences between intervals with and without the code
366 * sequence to be timed.
369 * The PARAMETER REGISTER must contain 0. There are no other
373 * On exit, the RETURN REGISTER contains:
374 * - The number of centiseconds since some arbitrary start
375 * point, if the call is successful.
376 * - –1 if the call is not successful. For example, because
377 * of a communications error.
380 clock_t delta
= clock() - semihosting
->setup_time
;
382 semihosting
->result
= delta
/ (CLOCKS_PER_SEC
/ 100);
386 case SEMIHOSTING_SYS_CLOSE
: /* 0x02 */
388 * Closes a file on the host system. The handle must reference
389 * a file that was opened with SYS_OPEN.
392 * On entry, the PARAMETER REGISTER contains a pointer to a
393 * one-field argument block:
394 * - field 1 Contains a handle for an open file.
397 * On exit, the RETURN REGISTER contains:
398 * - 0 if the call is successful
399 * - –1 if the call is not successful.
401 retval
= semihosting_read_fields(target
, 1, fields
);
402 if (retval
!= ERROR_OK
)
405 int fd
= semihosting_get_field(target
, 0, fields
);
406 /* Do not allow to close OpenOCD's own standard streams */
407 if (fd
== 0 || fd
== 1 || fd
== 2) {
408 LOG_DEBUG("ignoring semihosting attempt to close %s",
409 (fd
== 0) ? "stdin" :
410 (fd
== 1) ? "stdout" : "stderr");
411 /* Just pretend success */
412 if (semihosting
->is_fileio
) {
413 semihosting
->result
= 0;
415 semihosting
->result
= 0;
416 semihosting
->sys_errno
= 0;
420 /* Close the descriptor */
421 if (semihosting
->is_fileio
) {
422 semihosting
->hit_fileio
= true;
423 fileio_info
->identifier
= "close";
424 fileio_info
->param_1
= fd
;
426 semihosting
->result
= close(fd
);
427 semihosting
->sys_errno
= errno
;
428 LOG_DEBUG("close(%d)=%d", fd
, (int)semihosting
->result
);
433 case SEMIHOSTING_SYS_ERRNO
: /* 0x13 */
435 * Returns the value of the C library errno variable that is
436 * associated with the semihosting implementation. The errno
437 * variable can be set by a number of C library semihosted
438 * functions, including:
446 * Whether errno is set or not, and to what value, is entirely
447 * host-specific, except where the ISO C standard defines the
451 * There are no parameters. The PARAMETER REGISTER must be 0.
454 * On exit, the RETURN REGISTER contains the value of the C
455 * library errno variable.
457 semihosting
->result
= semihosting
->sys_errno
;
460 case SEMIHOSTING_SYS_EXIT
: /* 0x18 */
462 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
463 * previous versions of the documentation.
465 * An application calls this operation to report an exception
466 * to the debugger directly. The most common use is to report
467 * that execution has completed, using ADP_Stopped_ApplicationExit.
469 * Note: This semihosting operation provides no means for 32-bit
470 * callers to indicate an application exit with a specified exit
471 * code. Semihosting callers may prefer to check for the presence
472 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
473 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
477 * On entry, the PARAMETER register is set to a reason code
478 * describing the cause of the trap. Not all semihosting client
479 * implementations will necessarily trap every corresponding
480 * event. Important reason codes are:
482 * - ADP_Stopped_ApplicationExit 0x20026
483 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
486 * On entry, the PARAMETER REGISTER contains a pointer to a
487 * two-field argument block:
488 * - field 1 The exception type, which is one of the set of
489 * reason codes in the above tables.
490 * - field 2 A subcode, whose meaning depends on the reason
492 * In particular, if field 1 is ADP_Stopped_ApplicationExit
493 * then field 2 is an exit status code, as passed to the C
494 * standard library exit() function. A simulator receiving
495 * this request must notify a connected debugger, if present,
496 * and then exit with the specified status.
499 * No return is expected from these calls. However, it is
500 * possible for the debugger to request that the application
501 * continues by performing an RDI_Execute request or equivalent.
502 * In this case, execution continues with the registers as they
503 * were on entry to the operation, or as subsequently modified
506 if (semihosting
->word_size_bytes
== 8) {
507 retval
= semihosting_read_fields(target
, 2, fields
);
508 if (retval
!= ERROR_OK
)
511 int type
= semihosting_get_field(target
, 0, fields
);
512 int code
= semihosting_get_field(target
, 1, fields
);
514 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
515 if (!gdb_actual_connections
)
519 "semihosting: *** application exited with %d ***\n",
524 "semihosting: application exception %#x\n",
529 if (semihosting
->param
== ADP_STOPPED_APPLICATION_EXIT
) {
530 if (!gdb_actual_connections
)
534 "semihosting: *** application exited normally ***\n");
536 } else if (semihosting
->param
== ADP_STOPPED_RUN_TIME_ERROR
) {
537 /* Chosen more or less arbitrarily to have a nicer message,
538 * otherwise all other return the same exit code 1. */
539 if (!gdb_actual_connections
)
543 "semihosting: *** application exited with error ***\n");
546 if (!gdb_actual_connections
)
550 "semihosting: application exception %#x\n",
551 (unsigned) semihosting
->param
);
555 if (!semihosting
->has_resumable_exit
) {
556 semihosting
->is_resumable
= false;
557 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
561 case SEMIHOSTING_SYS_EXIT_EXTENDED
: /* 0x20 */
563 * This operation is only supported if the semihosting extension
564 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
565 * reported using feature byte 0, bit 0. If this extension is
566 * supported, then the implementation provides a means to
567 * report a normal exit with a nonzero exit status in both 32-bit
568 * and 64-bit semihosting APIs.
570 * The implementation must provide the semihosting call
571 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
573 * SYS_EXIT_EXTENDED is used by an application to report an
574 * exception or exit to the debugger directly. The most common
575 * use is to report that execution has completed, using
576 * ADP_Stopped_ApplicationExit.
579 * On entry, the PARAMETER REGISTER contains a pointer to a
580 * two-field argument block:
581 * - field 1 The exception type, which should be one of the set
582 * of reason codes that are documented for the SYS_EXIT
583 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
584 * - field 2 A subcode, whose meaning depends on the reason
585 * code in field 1. In particular, if field 1 is
586 * ADP_Stopped_ApplicationExit then field 2 is an exit status
587 * code, as passed to the C standard library exit() function.
588 * A simulator receiving this request must notify a connected
589 * debugger, if present, and then exit with the specified status.
592 * No return is expected from these calls.
594 * For the A64 API, this call is identical to the behavior of
595 * the mandatory SYS_EXIT (0x18) call. If this extension is
596 * supported, then both calls must be implemented.
598 retval
= semihosting_read_fields(target
, 2, fields
);
599 if (retval
!= ERROR_OK
)
602 int type
= semihosting_get_field(target
, 0, fields
);
603 int code
= semihosting_get_field(target
, 1, fields
);
605 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
606 if (!gdb_actual_connections
)
610 "semihosting: *** application exited with %d ***\n",
614 fprintf(stderr
, "semihosting: exception %#x\n",
618 if (!semihosting
->has_resumable_exit
) {
619 semihosting
->is_resumable
= false;
620 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
624 case SEMIHOSTING_SYS_FLEN
: /* 0x0C */
626 * Returns the length of a specified file.
629 * On entry, the PARAMETER REGISTER contains a pointer to a
630 * one-field argument block:
631 * - field 1 A handle for a previously opened, seekable file
635 * On exit, the RETURN REGISTER contains:
636 * - The current length of the file object, if the call is
638 * - –1 if an error occurs.
640 if (semihosting
->is_fileio
) {
641 semihosting
->result
= -1;
642 semihosting
->sys_errno
= EINVAL
;
644 retval
= semihosting_read_fields(target
, 1, fields
);
645 if (retval
!= ERROR_OK
)
648 int fd
= semihosting_get_field(target
, 0, fields
);
650 semihosting
->result
= fstat(fd
, &buf
);
651 if (semihosting
->result
== -1) {
652 semihosting
->sys_errno
= errno
;
653 LOG_DEBUG("fstat(%d)=%d", fd
, (int)semihosting
->result
);
656 LOG_DEBUG("fstat(%d)=%d", fd
, (int)semihosting
->result
);
657 semihosting
->result
= buf
.st_size
;
661 case SEMIHOSTING_SYS_GET_CMDLINE
: /* 0x15 */
663 * Returns the command line that is used for the call to the
664 * executable, that is, argc and argv.
667 * On entry, the PARAMETER REGISTER points to a two-field data
668 * block to be used for returning the command string and its length:
669 * - field 1 A pointer to a buffer of at least the size that is
670 * specified in field 2.
671 * - field 2 The length of the buffer in bytes.
675 * If the call is successful, then the RETURN REGISTER contains 0,
676 * the PARAMETER REGISTER is unchanged, and the data block is
677 * updated as follows:
678 * - field 1 A pointer to a null-terminated string of the command
680 * - field 2 The length of the string in bytes.
681 * If the call is not successful, then the RETURN REGISTER
684 * Note: The semihosting implementation might impose limits on
685 * the maximum length of the string that can be transferred.
686 * However, the implementation must be able to support a
687 * command-line length of at least 80 bytes.
689 retval
= semihosting_read_fields(target
, 2, fields
);
690 if (retval
!= ERROR_OK
)
693 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
694 size_t size
= semihosting_get_field(target
, 1, fields
);
696 char *arg
= semihosting
->cmdline
?
697 semihosting
->cmdline
: "";
698 uint32_t len
= strlen(arg
) + 1;
700 semihosting
->result
= -1;
702 semihosting_set_field(target
, len
, 1, fields
);
703 retval
= target_write_buffer(target
, addr
, len
,
705 if (retval
!= ERROR_OK
)
707 semihosting
->result
= 0;
709 retval
= semihosting_write_fields(target
, 2, fields
);
710 if (retval
!= ERROR_OK
)
713 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg
,
714 (int)semihosting
->result
);
718 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
720 * Returns the system stack and heap parameters.
723 * On entry, the PARAMETER REGISTER contains the address of a
724 * pointer to a four-field data block. The contents of the data
725 * block are filled by the function. The following C-like
726 * pseudocode describes the layout of the block:
735 * On exit, the PARAMETER REGISTER is unchanged and the data
736 * block has been updated.
738 retval
= semihosting_read_fields(target
, 1, fields
);
739 if (retval
!= ERROR_OK
)
742 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
743 /* tell the remote we have no idea */
744 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
745 retval
= target_write_memory(target
, addr
, 4,
746 semihosting
->word_size_bytes
,
748 if (retval
!= ERROR_OK
)
750 semihosting
->result
= 0;
754 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
756 * Determines whether the return code from another semihosting
757 * call is an error status or not.
759 * This call is passed a parameter block containing the error
763 * On entry, the PARAMETER REGISTER contains a pointer to a
764 * one-field data block:
765 * - field 1 The required status word to check.
768 * On exit, the RETURN REGISTER contains:
769 * - 0 if the status field is not an error indication
770 * - A nonzero value if the status field is an error indication.
772 retval
= semihosting_read_fields(target
, 1, fields
);
773 if (retval
!= ERROR_OK
)
776 uint64_t code
= semihosting_get_field(target
, 0, fields
);
777 semihosting
->result
= (code
!= 0);
780 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
782 * Checks whether a file is connected to an interactive device.
785 * On entry, the PARAMETER REGISTER contains a pointer to a
786 * one-field argument block:
787 * field 1 A handle for a previously opened file object.
790 * On exit, the RETURN REGISTER contains:
791 * - 1 if the handle identifies an interactive device.
792 * - 0 if the handle identifies a file.
793 * - A value other than 1 or 0 if an error occurs.
795 if (semihosting
->is_fileio
) {
796 semihosting
->hit_fileio
= true;
797 fileio_info
->identifier
= "isatty";
798 fileio_info
->param_1
= semihosting
->param
;
800 retval
= semihosting_read_fields(target
, 1, fields
);
801 if (retval
!= ERROR_OK
)
803 int fd
= semihosting_get_field(target
, 0, fields
);
804 semihosting
->result
= isatty(fd
);
805 semihosting
->sys_errno
= errno
;
806 LOG_DEBUG("isatty(%d)=%d", fd
, (int)semihosting
->result
);
810 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
812 * Opens a file on the host system.
814 * The file path is specified either as relative to the current
815 * directory of the host process, or absolute, using the path
816 * conventions of the host operating system.
818 * Semihosting implementations must support opening the special
819 * path name :semihosting-features as part of the semihosting
820 * extensions reporting mechanism.
822 * ARM targets interpret the special path name :tt as meaning
823 * the console input stream, for an open-read or the console
824 * output stream, for an open-write. Opening these streams is
825 * performed as part of the standard startup code for those
826 * applications that reference the C stdio streams. The
827 * semihosting extension SH_EXT_STDOUT_STDERR allows the
828 * semihosting caller to open separate output streams
829 * corresponding to stdout and stderr. This extension is
830 * reported using feature byte 0, bit 1. Use SYS_OPEN with
831 * the special path name :semihosting-features to access the
834 * If this extension is supported, the implementation must
835 * support the following additional semantics to SYS_OPEN:
836 * - If the special path name :tt is opened with an fopen
837 * mode requesting write access (w, wb, w+, or w+b), then
838 * this is a request to open stdout.
839 * - If the special path name :tt is opened with a mode
840 * requesting append access (a, ab, a+, or a+b), then this is
841 * a request to open stderr.
844 * On entry, the PARAMETER REGISTER contains a pointer to a
845 * three-field argument block:
846 * - field 1 A pointer to a null-terminated string containing
847 * a file or device name.
848 * - field 2 An integer that specifies the file opening mode.
849 * - field 3 An integer that gives the length of the string
850 * pointed to by field 1.
852 * The length does not include the terminating null character
853 * that must be present.
856 * On exit, the RETURN REGISTER contains:
857 * - A nonzero handle if the call is successful.
858 * - –1 if the call is not successful.
860 retval
= semihosting_read_fields(target
, 3, fields
);
861 if (retval
!= ERROR_OK
)
864 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
865 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
866 size_t len
= semihosting_get_field(target
, 2, fields
);
869 semihosting
->result
= -1;
870 semihosting
->sys_errno
= EINVAL
;
873 uint8_t *fn
= malloc(len
+1);
875 semihosting
->result
= -1;
876 semihosting
->sys_errno
= ENOMEM
;
878 retval
= target_read_memory(target
, addr
, 1, len
, fn
);
879 if (retval
!= ERROR_OK
) {
884 /* TODO: implement the :semihosting-features special file.
886 if (semihosting
->is_fileio
) {
887 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
888 semihosting
->result
= -1;
889 semihosting
->sys_errno
= EINVAL
;
890 } else if (strcmp((char *)fn
, ":tt") == 0) {
892 semihosting
->result
= 0;
894 semihosting
->result
= 1;
896 semihosting
->result
= 2;
898 semihosting
->result
= -1;
900 semihosting
->hit_fileio
= true;
901 fileio_info
->identifier
= "open";
902 fileio_info
->param_1
= addr
;
903 fileio_info
->param_2
= len
;
904 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
905 fileio_info
->param_4
= 0644;
908 if (strcmp((char *)fn
, ":tt") == 0) {
910 * - 0-3 ("r") for stdin,
911 * - 4-7 ("w") for stdout,
912 * - 8-11 ("a") for stderr */
914 int fd
= dup(STDIN_FILENO
);
915 semihosting
->result
= fd
;
916 semihosting
->stdin_fd
= fd
;
917 semihosting
->sys_errno
= errno
;
918 LOG_DEBUG("dup(STDIN)=%d",
919 (int)semihosting
->result
);
920 } else if (mode
< 8) {
921 int fd
= dup(STDOUT_FILENO
);
922 semihosting
->result
= fd
;
923 semihosting
->stdout_fd
= fd
;
924 semihosting
->sys_errno
= errno
;
925 LOG_DEBUG("dup(STDOUT)=%d",
926 (int)semihosting
->result
);
928 int fd
= dup(STDERR_FILENO
);
929 semihosting
->result
= fd
;
930 semihosting
->stderr_fd
= fd
;
931 semihosting
->sys_errno
= errno
;
932 LOG_DEBUG("dup(STDERR)=%d",
933 (int)semihosting
->result
);
936 /* cygwin requires the permission setting
937 * otherwise it will fail to reopen a previously
939 semihosting
->result
= open((char *)fn
,
940 open_host_modeflags
[mode
],
942 semihosting
->sys_errno
= errno
;
943 LOG_DEBUG("open('%s')=%d", fn
,
944 (int)semihosting
->result
);
952 case SEMIHOSTING_SYS_READ
: /* 0x06 */
954 * Reads the contents of a file into a buffer. The file position
955 * is specified either:
956 * - Explicitly by a SYS_SEEK.
957 * - Implicitly one byte beyond the previous SYS_READ or
960 * The file position is at the start of the file when it is
961 * opened, and is lost when the file is closed. Perform the
962 * file operation as a single action whenever possible. For
963 * example, do not split a read of 16KB into four 4KB chunks
964 * unless there is no alternative.
967 * On entry, the PARAMETER REGISTER contains a pointer to a
968 * three-field data block:
969 * - field 1 Contains a handle for a file previously opened
971 * - field 2 Points to a buffer.
972 * - field 3 Contains the number of bytes to read to the buffer
976 * On exit, the RETURN REGISTER contains the number of bytes not
977 * filled in the buffer (buffer_length - bytes_read) as follows:
978 * - If the RETURN REGISTER is 0, the entire buffer was
979 * successfully filled.
980 * - If the RETURN REGISTER is the same as field 3, no bytes
981 * were read (EOF can be assumed).
982 * - If the RETURN REGISTER contains a value smaller than
983 * field 3, the read succeeded but the buffer was only partly
984 * filled. For interactive devices, this is the most common
987 retval
= semihosting_read_fields(target
, 3, fields
);
988 if (retval
!= ERROR_OK
)
991 int fd
= semihosting_get_field(target
, 0, fields
);
992 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
993 size_t len
= semihosting_get_field(target
, 2, fields
);
994 if (semihosting
->is_fileio
) {
995 semihosting
->hit_fileio
= true;
996 fileio_info
->identifier
= "read";
997 fileio_info
->param_1
= fd
;
998 fileio_info
->param_2
= addr
;
999 fileio_info
->param_3
= len
;
1001 uint8_t *buf
= malloc(len
);
1003 semihosting
->result
= -1;
1004 semihosting
->sys_errno
= ENOMEM
;
1006 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
1007 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%d",
1011 (int)semihosting
->result
);
1012 if (semihosting
->result
>= 0) {
1013 retval
= target_write_buffer(target
, addr
,
1014 semihosting
->result
,
1016 if (retval
!= ERROR_OK
) {
1020 /* the number of bytes NOT filled in */
1021 semihosting
->result
= len
-
1022 semihosting
->result
;
1030 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1032 * Reads a byte from the console.
1035 * The PARAMETER REGISTER must contain 0. There are no other
1036 * parameters or values possible.
1039 * On exit, the RETURN REGISTER contains the byte read from
1042 if (semihosting
->is_fileio
) {
1043 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1046 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1047 LOG_DEBUG("getchar()=%d", (int)semihosting
->result
);
1050 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1052 * Deletes a specified file on the host filing system.
1055 * On entry, the PARAMETER REGISTER contains a pointer to a
1056 * two-field argument block:
1057 * - field 1 Points to a null-terminated string that gives the
1058 * path name of the file to be deleted.
1059 * - field 2 The length of the string.
1062 * On exit, the RETURN REGISTER contains:
1063 * - 0 if the delete is successful
1064 * - A nonzero, host-specific error code if the delete fails.
1066 retval
= semihosting_read_fields(target
, 2, fields
);
1067 if (retval
!= ERROR_OK
)
1070 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1071 size_t len
= semihosting_get_field(target
, 1, fields
);
1072 if (semihosting
->is_fileio
) {
1073 semihosting
->hit_fileio
= true;
1074 fileio_info
->identifier
= "unlink";
1075 fileio_info
->param_1
= addr
;
1076 fileio_info
->param_2
= len
;
1078 uint8_t *fn
= malloc(len
+1);
1080 semihosting
->result
= -1;
1081 semihosting
->sys_errno
= ENOMEM
;
1084 target_read_memory(target
, addr
, 1, len
,
1086 if (retval
!= ERROR_OK
) {
1091 semihosting
->result
= remove((char *)fn
);
1092 semihosting
->sys_errno
= errno
;
1093 LOG_DEBUG("remove('%s')=%d", fn
,
1094 (int)semihosting
->result
);
1102 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1104 * Renames a specified file.
1107 * On entry, the PARAMETER REGISTER contains a pointer to a
1108 * four-field data block:
1109 * - field 1 A pointer to the name of the old file.
1110 * - field 2 The length of the old filename.
1111 * - field 3 A pointer to the new filename.
1112 * - field 4 The length of the new filename. Both strings are
1116 * On exit, the RETURN REGISTER contains:
1117 * - 0 if the rename is successful.
1118 * - A nonzero, host-specific error code if the rename fails.
1120 retval
= semihosting_read_fields(target
, 4, fields
);
1121 if (retval
!= ERROR_OK
)
1124 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1125 size_t len1
= semihosting_get_field(target
, 1, fields
);
1126 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1127 size_t len2
= semihosting_get_field(target
, 3, fields
);
1128 if (semihosting
->is_fileio
) {
1129 semihosting
->hit_fileio
= true;
1130 fileio_info
->identifier
= "rename";
1131 fileio_info
->param_1
= addr1
;
1132 fileio_info
->param_2
= len1
;
1133 fileio_info
->param_3
= addr2
;
1134 fileio_info
->param_4
= len2
;
1136 uint8_t *fn1
= malloc(len1
+1);
1137 uint8_t *fn2
= malloc(len2
+1);
1141 semihosting
->result
= -1;
1142 semihosting
->sys_errno
= ENOMEM
;
1144 retval
= target_read_memory(target
, addr1
, 1, len1
,
1146 if (retval
!= ERROR_OK
) {
1151 retval
= target_read_memory(target
, addr2
, 1, len2
,
1153 if (retval
!= ERROR_OK
) {
1160 semihosting
->result
= rename((char *)fn1
,
1162 semihosting
->sys_errno
= errno
;
1163 LOG_DEBUG("rename('%s', '%s')=%d", fn1
, fn2
,
1164 (int)semihosting
->result
);
1173 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1175 * Seeks to a specified position in a file using an offset
1176 * specified from the start of the file. The file is assumed
1177 * to be a byte array and the offset is given in bytes.
1180 * On entry, the PARAMETER REGISTER contains a pointer to a
1181 * two-field data block:
1182 * - field 1 A handle for a seekable file object.
1183 * - field 2 The absolute byte position to seek to.
1186 * On exit, the RETURN REGISTER contains:
1187 * - 0 if the request is successful.
1188 * - A negative value if the request is not successful.
1189 * Use SYS_ERRNO to read the value of the host errno variable
1190 * describing the error.
1192 * Note: The effect of seeking outside the current extent of
1193 * the file object is undefined.
1195 retval
= semihosting_read_fields(target
, 2, fields
);
1196 if (retval
!= ERROR_OK
)
1199 int fd
= semihosting_get_field(target
, 0, fields
);
1200 off_t pos
= semihosting_get_field(target
, 1, fields
);
1201 if (semihosting
->is_fileio
) {
1202 semihosting
->hit_fileio
= true;
1203 fileio_info
->identifier
= "lseek";
1204 fileio_info
->param_1
= fd
;
1205 fileio_info
->param_2
= pos
;
1206 fileio_info
->param_3
= SEEK_SET
;
1208 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1209 semihosting
->sys_errno
= errno
;
1210 LOG_DEBUG("lseek(%d, %d)=%d", fd
, (int)pos
,
1211 (int)semihosting
->result
);
1212 if (semihosting
->result
== pos
)
1213 semihosting
->result
= 0;
1218 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1220 * Passes a command to the host command-line interpreter.
1221 * This enables you to execute a system command such as dir,
1222 * ls, or pwd. The terminal I/O is on the host, and is not
1223 * visible to the target.
1226 * On entry, the PARAMETER REGISTER contains a pointer to a
1227 * two-field argument block:
1228 * - field 1 Points to a string to be passed to the host
1229 * command-line interpreter.
1230 * - field 2 The length of the string.
1233 * On exit, the RETURN REGISTER contains the return status.
1236 /* Provide SYS_SYSTEM functionality. Uses the
1237 * libc system command, there may be a reason *NOT*
1238 * to use this, but as I can't think of one, I
1239 * implemented it this way.
1241 retval
= semihosting_read_fields(target
, 2, fields
);
1242 if (retval
!= ERROR_OK
)
1245 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1246 size_t len
= semihosting_get_field(target
, 1, fields
);
1247 if (semihosting
->is_fileio
) {
1248 semihosting
->hit_fileio
= true;
1249 fileio_info
->identifier
= "system";
1250 fileio_info
->param_1
= addr
;
1251 fileio_info
->param_2
= len
;
1253 uint8_t *cmd
= malloc(len
+1);
1255 semihosting
->result
= -1;
1256 semihosting
->sys_errno
= ENOMEM
;
1258 retval
= target_read_memory(target
,
1263 if (retval
!= ERROR_OK
) {
1268 semihosting
->result
= system(
1270 LOG_DEBUG("system('%s')=%d",
1272 (int)semihosting
->result
);
1281 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1283 * Returns the number of seconds since 00:00 January 1, 1970.
1284 * This value is real-world time, regardless of any debug agent
1288 * There are no parameters.
1291 * On exit, the RETURN REGISTER contains the number of seconds.
1293 semihosting
->result
= time(NULL
);
1296 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1298 * Writes the contents of a buffer to a specified file at the
1299 * current file position. The file position is specified either:
1300 * - Explicitly, by a SYS_SEEK.
1301 * - Implicitly as one byte beyond the previous SYS_READ or
1302 * SYS_WRITE request.
1304 * The file position is at the start of the file when the file
1305 * is opened, and is lost when the file is closed.
1307 * Perform the file operation as a single action whenever
1308 * possible. For example, do not split a write of 16KB into
1309 * four 4KB chunks unless there is no alternative.
1312 * On entry, the PARAMETER REGISTER contains a pointer to a
1313 * three-field data block:
1314 * - field 1 Contains a handle for a file previously opened
1316 * - field 2 Points to the memory containing the data to be written.
1317 * - field 3 Contains the number of bytes to be written from
1318 * the buffer to the file.
1321 * On exit, the RETURN REGISTER contains:
1322 * - 0 if the call is successful.
1323 * - The number of bytes that are not written, if there is an error.
1325 retval
= semihosting_read_fields(target
, 3, fields
);
1326 if (retval
!= ERROR_OK
)
1329 int fd
= semihosting_get_field(target
, 0, fields
);
1330 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1331 size_t len
= semihosting_get_field(target
, 2, fields
);
1332 if (semihosting
->is_fileio
) {
1333 semihosting
->hit_fileio
= true;
1334 fileio_info
->identifier
= "write";
1335 fileio_info
->param_1
= fd
;
1336 fileio_info
->param_2
= addr
;
1337 fileio_info
->param_3
= len
;
1339 uint8_t *buf
= malloc(len
);
1341 semihosting
->result
= -1;
1342 semihosting
->sys_errno
= ENOMEM
;
1344 retval
= target_read_buffer(target
, addr
, len
, buf
);
1345 if (retval
!= ERROR_OK
) {
1349 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1350 semihosting
->sys_errno
= errno
;
1351 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%d",
1355 (int)semihosting
->result
);
1356 if (semihosting
->result
>= 0) {
1357 /* The number of bytes that are NOT written.
1359 semihosting
->result
= len
-
1360 semihosting
->result
;
1369 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1371 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1372 * to the debug channel. When executed under a semihosting
1373 * debugger, the character appears on the host debugger console.
1376 * On entry, the PARAMETER REGISTER contains a pointer to the
1380 * None. The RETURN REGISTER is corrupted.
1382 if (semihosting
->is_fileio
) {
1383 semihosting
->hit_fileio
= true;
1384 fileio_info
->identifier
= "write";
1385 fileio_info
->param_1
= 1;
1386 fileio_info
->param_2
= semihosting
->param
;
1387 fileio_info
->param_3
= 1;
1389 uint64_t addr
= semihosting
->param
;
1391 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1392 if (retval
!= ERROR_OK
)
1394 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1395 semihosting
->result
= 0;
1399 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1401 * Writes a null-terminated string to the debug channel.
1402 * When executed under a semihosting debugger, the characters
1403 * appear on the host debugger console.
1406 * On entry, the PARAMETER REGISTER contains a pointer to the
1407 * first byte of the string.
1410 * None. The RETURN REGISTER is corrupted.
1412 if (semihosting
->is_fileio
) {
1414 uint64_t addr
= semihosting
->param
;
1417 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1418 if (retval
!= ERROR_OK
)
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
= count
;
1430 uint64_t addr
= semihosting
->param
;
1433 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1434 if (retval
!= ERROR_OK
)
1438 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1440 semihosting
->result
= 0;
1444 case SEMIHOSTING_USER_CMD_0x100
... SEMIHOSTING_USER_CMD_0x107
:
1446 * This is a user defined operation (while user cmds 0x100-0x1ff
1447 * are possible, only 0x100-0x107 are currently implemented).
1449 * Reads the user operation parameters from target, then fires the
1450 * corresponding target event. When the target callbacks returned,
1451 * cleans up the command parameter buffer.
1454 * On entry, the PARAMETER REGISTER contains a pointer to a
1455 * two-field data block:
1456 * - field 1 Contains a pointer to the bound command parameter
1458 * - field 2 Contains the command parameter string length
1461 * On exit, the RETURN REGISTER contains the return status.
1464 assert(!semihosting_user_op_params
);
1466 retval
= semihosting_read_fields(target
, 2, fields
);
1467 if (retval
!= ERROR_OK
) {
1468 LOG_ERROR("Failed to read fields for user defined command"
1469 " op=0x%x", semihosting
->op
);
1473 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1475 size_t len
= semihosting_get_field(target
, 1, fields
);
1476 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1477 LOG_ERROR("The maximum length for user defined command "
1478 "parameter is %u, received length is %zu (op=0x%x)",
1479 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1485 semihosting_user_op_params
= malloc(len
+ 1);
1486 if (!semihosting_user_op_params
)
1488 semihosting_user_op_params
[len
] = 0;
1490 retval
= target_read_buffer(target
, addr
, len
,
1491 (uint8_t *)(semihosting_user_op_params
));
1492 if (retval
!= ERROR_OK
) {
1493 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1495 free(semihosting_user_op_params
);
1496 semihosting_user_op_params
= NULL
;
1500 target_handle_event(target
, semihosting
->op
);
1501 free(semihosting_user_op_params
);
1502 semihosting_user_op_params
= NULL
;
1504 semihosting
->result
= 0;
1509 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1511 * Returns the number of elapsed target ticks since execution
1513 * Use SYS_TICKFREQ to determine the tick frequency.
1516 * On entry, the PARAMETER REGISTER points to a two-field data
1517 * block to be used for returning the number of elapsed ticks:
1518 * - field 1 The least significant field and is at the low address.
1519 * - field 2 The most significant field and is at the high address.
1522 * On entry the PARAMETER REGISTER points to a one-field data
1523 * block to be used for returning the number of elapsed ticks:
1524 * - field 1 The number of elapsed ticks as a 64-bit value.
1528 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1529 * REGISTER is unchanged, and the data block pointed to by the
1530 * PARAMETER REGISTER is filled in with the number of elapsed
1532 * - On failure, the RETURN REGISTER contains -1, and the
1533 * PARAMETER REGISTER contains -1.
1535 * Note: Some semihosting implementations might not support this
1536 * semihosting operation, and they always return -1 in the
1540 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1542 * Returns the tick frequency.
1545 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1548 * On exit, the RETURN REGISTER contains either:
1549 * - The number of ticks per second.
1550 * - –1 if the target does not know the value of one tick.
1552 * Note: Some semihosting implementations might not support
1553 * this semihosting operation, and they always return -1 in the
1557 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1559 * Returns a temporary name for a file identified by a system
1563 * On entry, the PARAMETER REGISTER contains a pointer to a
1564 * three-word argument block:
1565 * - field 1 A pointer to a buffer.
1566 * - field 2 A target identifier for this filename. Its value
1567 * must be an integer in the range 0-255.
1568 * - field 3 Contains the length of the buffer. The length must
1569 * be at least the value of L_tmpnam on the host system.
1572 * On exit, the RETURN REGISTER contains:
1573 * - 0 if the call is successful.
1574 * - –1 if an error occurs.
1576 * The buffer pointed to by the PARAMETER REGISTER contains
1577 * the filename, prefixed with a suitable directory name.
1578 * If you use the same target identifier again, the same
1579 * filename is returned.
1581 * Note: The returned string must be null-terminated.
1585 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1586 (unsigned) semihosting
->op
);
1587 semihosting
->result
= -1;
1588 semihosting
->sys_errno
= ENOTSUP
;
1591 if (!semihosting
->hit_fileio
) {
1592 retval
= semihosting
->post_result(target
);
1593 if (retval
!= ERROR_OK
) {
1594 LOG_ERROR("Failed to post semihosting result");
1602 /* -------------------------------------------------------------------------
1603 * Local functions. */
1605 static int semihosting_common_fileio_info(struct target
*target
,
1606 struct gdb_fileio_info
*fileio_info
)
1608 struct semihosting
*semihosting
= target
->semihosting
;
1613 * To avoid unnecessary duplication, semihosting prepares the
1614 * fileio_info structure out-of-band when the target halts. See
1615 * do_semihosting for more detail.
1617 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1623 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1624 int fileio_errno
, bool ctrl_c
)
1626 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1627 struct semihosting
*semihosting
= target
->semihosting
;
1631 /* clear pending status */
1632 semihosting
->hit_fileio
= false;
1634 semihosting
->result
= result
;
1635 semihosting
->sys_errno
= fileio_errno
;
1638 * Some fileio results do not match up with what the semihosting
1639 * operation expects; for these operations, we munge the results
1642 switch (semihosting
->op
) {
1643 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1645 semihosting
->result
= fileio_info
->param_3
;
1647 semihosting
->result
= 0;
1650 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1651 if (result
== (int)fileio_info
->param_3
)
1652 semihosting
->result
= 0;
1654 semihosting
->result
= fileio_info
->param_3
;
1657 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1659 semihosting
->result
= 0;
1663 return semihosting
->post_result(target
);
1667 * Read all fields of a command from target to buffer.
1669 static int semihosting_read_fields(struct target
*target
, size_t number
,
1672 struct semihosting
*semihosting
= target
->semihosting
;
1673 /* Use 4-byte multiples to trigger fast memory access. */
1674 return target_read_memory(target
, semihosting
->param
, 4,
1675 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1679 * Write all fields of a command from buffer to target.
1681 static int semihosting_write_fields(struct target
*target
, size_t number
,
1684 struct semihosting
*semihosting
= target
->semihosting
;
1685 /* Use 4-byte multiples to trigger fast memory access. */
1686 return target_write_memory(target
, semihosting
->param
, 4,
1687 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1691 * Extract a field from the buffer, considering register size and endianness.
1693 static uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1696 struct semihosting
*semihosting
= target
->semihosting
;
1697 if (semihosting
->word_size_bytes
== 8)
1698 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1700 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1704 * Store a field in the buffer, considering register size and endianness.
1706 static void semihosting_set_field(struct target
*target
, uint64_t value
,
1710 struct semihosting
*semihosting
= target
->semihosting
;
1711 if (semihosting
->word_size_bytes
== 8)
1712 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1714 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1717 /* -------------------------------------------------------------------------
1718 * Semihosting redirect over TCP structs and functions */
1720 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1722 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1723 service
->semihosting
->tcp_connection
= connection
;
1728 static int semihosting_service_input_handler(struct connection
*connection
)
1730 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1732 if (!connection
->input_pending
) {
1733 /* consume received data, not for semihosting IO */
1734 const int buf_len
= 100;
1736 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1738 if (bytes_read
== 0) {
1739 return ERROR_SERVER_REMOTE_CLOSED
;
1740 } else if (bytes_read
== -1) {
1741 LOG_ERROR("error during read: %s", strerror(errno
));
1742 return ERROR_SERVER_REMOTE_CLOSED
;
1744 } else if (service
->error
!= ERROR_OK
) {
1745 return ERROR_SERVER_REMOTE_CLOSED
;
1751 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1753 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1755 free(service
->name
);
1762 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1764 if (!semihosting
->tcp_connection
)
1767 struct service
*service
= semihosting
->tcp_connection
->service
;
1768 remove_service(service
->name
, service
->port
);
1769 semihosting
->tcp_connection
= NULL
;
1773 static const struct service_driver semihosting_service_driver
= {
1774 .name
= "semihosting",
1775 .new_connection_during_keep_alive_handler
= NULL
,
1776 .new_connection_handler
= semihosting_service_new_connection_handler
,
1777 .input_handler
= semihosting_service_input_handler
,
1778 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1779 .keep_client_alive_handler
= NULL
,
1782 /* -------------------------------------------------------------------------
1783 * Common semihosting commands handlers. */
1785 COMMAND_HANDLER(handle_common_semihosting_command
)
1787 struct target
*target
= get_current_target(CMD_CTX
);
1790 LOG_ERROR("No target selected");
1794 struct semihosting
*semihosting
= target
->semihosting
;
1796 command_print(CMD
, "semihosting not supported for current target");
1803 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1805 if (!target_was_examined(target
)) {
1806 LOG_ERROR("Target not examined yet");
1810 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1811 LOG_ERROR("Failed to Configure semihosting");
1815 /* FIXME never let that "catch" be dropped! (???) */
1816 semihosting
->is_active
= is_active
;
1819 command_print(CMD
, "semihosting is %s",
1820 semihosting
->is_active
1821 ? "enabled" : "disabled");
1826 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1828 struct target
*target
= get_current_target(CMD_CTX
);
1830 if (target
== NULL
) {
1831 LOG_ERROR("No target selected");
1835 struct semihosting
*semihosting
= target
->semihosting
;
1837 command_print(CMD
, "semihosting not supported for current target");
1841 if (!semihosting
->is_active
) {
1842 command_print(CMD
, "semihosting not yet enabled for current target");
1846 enum semihosting_redirect_config cfg
;
1850 return ERROR_COMMAND_SYNTAX_ERROR
;
1852 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1853 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1855 return ERROR_COMMAND_SYNTAX_ERROR
;
1856 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1857 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1858 return ERROR_COMMAND_SYNTAX_ERROR
;
1862 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1863 if (CMD_ARGC
== 3) {
1864 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1865 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1866 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1867 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1868 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1869 return ERROR_COMMAND_SYNTAX_ERROR
;
1872 return ERROR_COMMAND_SYNTAX_ERROR
;
1875 semihosting_tcp_close_cnx(semihosting
);
1876 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1878 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1879 struct semihosting_tcp_service
*service
=
1880 calloc(1, sizeof(struct semihosting_tcp_service
));
1882 LOG_ERROR("Failed to allocate semihosting TCP service.");
1886 service
->semihosting
= semihosting
;
1888 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1889 if (!service
->name
) {
1890 LOG_ERROR("Out of memory");
1895 int ret
= add_service(&semihosting_service_driver
,
1898 if (ret
!= ERROR_OK
) {
1899 LOG_ERROR("failed to initialize %s", service
->name
);
1900 free(service
->name
);
1906 semihosting
->redirect_cfg
= cfg
;
1911 COMMAND_HANDLER(handle_common_semihosting_fileio_command
)
1913 struct target
*target
= get_current_target(CMD_CTX
);
1916 LOG_ERROR("No target selected");
1920 struct semihosting
*semihosting
= target
->semihosting
;
1922 command_print(CMD
, "semihosting not supported for current target");
1926 if (!semihosting
->is_active
) {
1927 command_print(CMD
, "semihosting not yet enabled for current target");
1932 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->is_fileio
);
1934 command_print(CMD
, "semihosting fileio is %s",
1935 semihosting
->is_fileio
1936 ? "enabled" : "disabled");
1941 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1943 struct target
*target
= get_current_target(CMD_CTX
);
1947 LOG_ERROR("No target selected");
1951 struct semihosting
*semihosting
= target
->semihosting
;
1953 command_print(CMD
, "semihosting not supported for current target");
1957 free(semihosting
->cmdline
);
1958 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
1960 for (i
= 1; i
< CMD_ARGC
; i
++) {
1961 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
1964 free(semihosting
->cmdline
);
1965 semihosting
->cmdline
= cmdline
;
1968 command_print(CMD
, "semihosting command line is [%s]",
1969 semihosting
->cmdline
);
1974 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
1976 struct target
*target
= get_current_target(CMD_CTX
);
1979 LOG_ERROR("No target selected");
1983 struct semihosting
*semihosting
= target
->semihosting
;
1985 command_print(CMD
, "semihosting not supported for current target");
1989 if (!semihosting
->is_active
) {
1990 command_print(CMD
, "semihosting not yet enabled for current target");
1995 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
1997 command_print(CMD
, "semihosting resumable exit is %s",
1998 semihosting
->has_resumable_exit
1999 ? "enabled" : "disabled");
2004 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
2006 struct target
*target
= get_current_target(CMD_CTX
);
2007 struct semihosting
*semihosting
= target
->semihosting
;
2010 return ERROR_COMMAND_SYNTAX_ERROR
;
2012 if (!semihosting
->is_active
) {
2013 LOG_ERROR("semihosting not yet enabled for current target");
2017 if (!semihosting_user_op_params
) {
2018 LOG_ERROR("This command is usable only from a registered user "
2019 "semihosting event callback.");
2023 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2028 const struct command_registration semihosting_common_handlers
[] = {
2030 .name
= "semihosting",
2031 .handler
= handle_common_semihosting_command
,
2032 .mode
= COMMAND_EXEC
,
2033 .usage
= "['enable'|'disable']",
2034 .help
= "activate support for semihosting operations",
2037 .name
= "semihosting_redirect",
2038 .handler
= handle_common_semihosting_redirect_command
,
2039 .mode
= COMMAND_EXEC
,
2040 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2041 .help
= "redirect semihosting IO",
2044 .name
= "semihosting_cmdline",
2045 .handler
= handle_common_semihosting_cmdline
,
2046 .mode
= COMMAND_EXEC
,
2047 .usage
= "arguments",
2048 .help
= "command line arguments to be passed to program",
2051 .name
= "semihosting_fileio",
2052 .handler
= handle_common_semihosting_fileio_command
,
2053 .mode
= COMMAND_EXEC
,
2054 .usage
= "['enable'|'disable']",
2055 .help
= "activate support for semihosting fileio operations",
2058 .name
= "semihosting_resexit",
2059 .handler
= handle_common_semihosting_resumable_exit_command
,
2060 .mode
= COMMAND_EXEC
,
2061 .usage
= "['enable'|'disable']",
2062 .help
= "activate support for semihosting resumable exit",
2065 .name
= "semihosting_read_user_param",
2066 .handler
= handle_common_semihosting_read_user_param_command
,
2067 .mode
= COMMAND_EXEC
,
2069 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2071 COMMAND_REGISTRATION_DONE