openocd: src/target: replace the GPL-2.0-or-later license tag
[fw/openocd] / src / target / semihosting_common.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2018 by Liviu Ionescu                                   *
5  *   <ilg@livius.net>                                                      *
6  *                                                                         *
7  *   Copyright (C) 2018 by Marvell Technology Group Ltd.                   *
8  *   Written by Nicolas Pitre <nico@marvell.com>                           *
9  *                                                                         *
10  *   Copyright (C) 2010 by Spencer Oliver                                  *
11  *   spen@spen-soft.co.uk                                                  *
12  *                                                                         *
13  *   Copyright (C) 2016 by Square, Inc.                                    *
14  *   Steven Stallion <stallion@squareup.com>                               *
15  ***************************************************************************/
16
17 /**
18  * @file
19  * Common ARM semihosting support.
20  *
21  * Semihosting enables code running on a target to use some of the I/O
22  * facilities on the host computer. The target application must be linked
23  * against a library that forwards operation requests by using  an
24  * instruction trapped by the debugger.
25  *
26  * Details can be found in
27  * "Semihosting for AArch32 and AArch64, Release 2.0"
28  * https://static.docs.arm.com/100863/0200/semihosting.pdf
29  * from ARM Ltd.
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "target.h"
37 #include "target_type.h"
38 #include "semihosting_common.h"
39
40 #include <helper/binarybuffer.h>
41 #include <helper/log.h>
42 #include <sys/stat.h>
43
44 /**
45  * It is not possible to use O_... flags defined in sys/stat.h because they
46  * are not guaranteed to match the values defined by the GDB Remote Protocol.
47  * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
48  */
49 enum {
50         TARGET_O_RDONLY = 0x000,
51         TARGET_O_WRONLY = 0x001,
52         TARGET_O_RDWR   = 0x002,
53         TARGET_O_APPEND = 0x008,
54         TARGET_O_CREAT  = 0x200,
55         TARGET_O_TRUNC  = 0x400,
56         /* O_EXCL=0x800 is not required in this implementation. */
57 };
58
59 /* GDB remote protocol does not differentiate between text and binary open modes. */
60 static const int open_gdb_modeflags[12] = {
61         TARGET_O_RDONLY,
62         TARGET_O_RDONLY,
63         TARGET_O_RDWR,
64         TARGET_O_RDWR,
65         TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
66         TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,
67         TARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_TRUNC,
68         TARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_TRUNC,
69         TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
70         TARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,
71         TARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_APPEND,
72         TARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_APPEND
73 };
74
75 static const int open_host_modeflags[12] = {
76         O_RDONLY,
77         O_RDONLY | O_BINARY,
78         O_RDWR,
79         O_RDWR   | O_BINARY,
80         O_WRONLY | O_CREAT | O_TRUNC,
81         O_WRONLY | O_CREAT | O_TRUNC  | O_BINARY,
82         O_RDWR   | O_CREAT | O_TRUNC,
83         O_RDWR   | O_CREAT | O_TRUNC  | O_BINARY,
84         O_WRONLY | O_CREAT | O_APPEND,
85         O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
86         O_RDWR   | O_CREAT | O_APPEND,
87         O_RDWR   | O_CREAT | O_APPEND | O_BINARY
88 };
89
90 static int semihosting_common_fileio_info(struct target *target,
91         struct gdb_fileio_info *fileio_info);
92 static int semihosting_common_fileio_end(struct target *target, int result,
93         int fileio_errno, bool ctrl_c);
94
95 /* Attempts to include gdb_server.h failed. */
96 extern int gdb_actual_connections;
97
98 /**
99  * Initialize common semihosting support.
100  *
101  * @param target Pointer to the target to initialize.
102  * @param setup
103  * @param post_result
104  * @return An error status if there is a problem during initialization.
105  */
106 int semihosting_common_init(struct target *target, void *setup,
107         void *post_result)
108 {
109         LOG_DEBUG(" ");
110
111         target->fileio_info = malloc(sizeof(*target->fileio_info));
112         if (!target->fileio_info) {
113                 LOG_ERROR("out of memory");
114                 return ERROR_FAIL;
115         }
116         memset(target->fileio_info, 0, sizeof(*target->fileio_info));
117
118         struct semihosting *semihosting;
119         semihosting = malloc(sizeof(*target->semihosting));
120         if (!semihosting) {
121                 LOG_ERROR("out of memory");
122                 return ERROR_FAIL;
123         }
124
125         semihosting->is_active = false;
126         semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
127         semihosting->tcp_connection = NULL;
128         semihosting->stdin_fd = -1;
129         semihosting->stdout_fd = -1;
130         semihosting->stderr_fd = -1;
131         semihosting->is_fileio = false;
132         semihosting->hit_fileio = false;
133         semihosting->is_resumable = false;
134         semihosting->has_resumable_exit = false;
135         semihosting->word_size_bytes = 0;
136         semihosting->op = -1;
137         semihosting->param = 0;
138         semihosting->result = -1;
139         semihosting->sys_errno = -1;
140         semihosting->cmdline = NULL;
141         semihosting->basedir = NULL;
142
143         /* If possible, update it in setup(). */
144         semihosting->setup_time = clock();
145
146         semihosting->setup = setup;
147         semihosting->post_result = post_result;
148         semihosting->user_command_extension = NULL;
149
150         target->semihosting = semihosting;
151
152         target->type->get_gdb_fileio_info = semihosting_common_fileio_info;
153         target->type->gdb_fileio_end = semihosting_common_fileio_end;
154
155         return ERROR_OK;
156 }
157
158 struct semihosting_tcp_service {
159         struct semihosting *semihosting;
160         char *name;
161         int error;
162 };
163
164 static bool semihosting_is_redirected(struct semihosting *semihosting, int fd)
165 {
166         if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_NONE)
167                 return false;
168
169         bool is_read_op = false;
170
171         switch (semihosting->op) {
172         /* check debug semihosting operations: READC, WRITEC and WRITE0 */
173         case SEMIHOSTING_SYS_READC:
174                 is_read_op = true;
175                 /* fall through */
176         case SEMIHOSTING_SYS_WRITEC:
177         case SEMIHOSTING_SYS_WRITE0:
178                 /* debug operations are redirected when CFG is either DEBUG or ALL */
179                 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_STDIO)
180                         return false;
181                 break;
182
183         /* check stdio semihosting operations: READ and WRITE */
184         case SEMIHOSTING_SYS_READ:
185                 is_read_op = true;
186                 /* fall through */
187         case SEMIHOSTING_SYS_WRITE:
188                 /* stdio operations are redirected when CFG is either STDIO or ALL */
189                 if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_DEBUG)
190                         return false;
191                 break;
192
193         default:
194                 return false;
195         }
196
197         if (is_read_op)
198                 return fd == semihosting->stdin_fd;
199
200         /* write operation */
201         return fd == semihosting->stdout_fd || fd == semihosting->stderr_fd;
202 }
203
204 static ssize_t semihosting_redirect_write(struct semihosting *semihosting, void *buf, int size)
205 {
206         if (!semihosting->tcp_connection) {
207                 LOG_ERROR("No connected TCP client for semihosting");
208                 semihosting->sys_errno = EBADF; /* Bad file number */
209                 return -1;
210         }
211
212         struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
213
214         int retval = connection_write(semihosting->tcp_connection, buf, size);
215
216         if (retval < 0)
217                 log_socket_error(service->name);
218
219         return retval;
220 }
221
222 static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void *buf, int size)
223 {
224         if (semihosting_is_redirected(semihosting, fd))
225                 return semihosting_redirect_write(semihosting, buf, size);
226
227         /* default write */
228         return write(fd, buf, size);
229 }
230
231 static ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size)
232 {
233         if (!semihosting->tcp_connection) {
234                 LOG_ERROR("No connected TCP client for semihosting");
235                 semihosting->sys_errno = EBADF; /* Bad file number */
236                 return -1;
237         }
238
239         struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
240
241         service->error = ERROR_OK;
242         semihosting->tcp_connection->input_pending = true;
243
244         int retval = connection_read(semihosting->tcp_connection, buf, size);
245
246         if (retval <= 0)
247                 service->error = ERROR_SERVER_REMOTE_CLOSED;
248
249         if (retval < 0)
250                 log_socket_error(service->name);
251
252         semihosting->tcp_connection->input_pending = false;
253
254         return retval;
255 }
256
257 static inline int semihosting_putchar(struct semihosting *semihosting, int fd, int c)
258 {
259         if (semihosting_is_redirected(semihosting, fd))
260                 return semihosting_redirect_write(semihosting, &c, 1);
261
262         /* default putchar */
263         return putchar(c);
264 }
265
266 static inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, void *buf, int size)
267 {
268         if (semihosting_is_redirected(semihosting, fd))
269                 return semihosting_redirect_read(semihosting, buf, size);
270
271         /* default read */
272         ssize_t result = read(fd, buf, size);
273         semihosting->sys_errno = errno;
274
275         return result;
276 }
277
278 static inline int semihosting_getchar(struct semihosting *semihosting, int fd)
279 {
280         if (semihosting_is_redirected(semihosting, fd)) {
281                 unsigned char c;
282
283                 if (semihosting_redirect_read(semihosting, &c, 1) > 0)
284                         return c;
285
286                 return EOF;
287         }
288
289         /* default getchar */
290         return getchar();
291 }
292
293 /**
294  * User operation parameter string storage buffer. Contains valid data when the
295  * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
296  */
297 static char *semihosting_user_op_params;
298
299 /**
300  * Portable implementation of ARM semihosting calls.
301  * Performs the currently pending semihosting operation
302  * encoded in target->semihosting.
303  */
304 int semihosting_common(struct target *target)
305 {
306         struct semihosting *semihosting = target->semihosting;
307         if (!semihosting) {
308                 /* Silently ignore if the semihosting field was not set. */
309                 return ERROR_OK;
310         }
311
312         struct gdb_fileio_info *fileio_info = target->fileio_info;
313
314         /*
315          * By default return an error.
316          * The actual result must be set by each function
317          */
318         semihosting->result = -1;
319
320         /* Most operations are resumable, except the two exit calls. */
321         semihosting->is_resumable = true;
322
323         int retval;
324
325         /* Enough space to hold 4 long words. */
326         uint8_t fields[4*8];
327
328         LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op,
329                 semihosting->param);
330
331         switch (semihosting->op) {
332
333                 case SEMIHOSTING_SYS_CLOCK:     /* 0x10 */
334                         /*
335                          * Returns the number of centiseconds (hundredths of a second)
336                          * since the execution started.
337                          *
338                          * Values returned can be of limited use for some benchmarking
339                          * purposes because of communication overhead or other
340                          * agent-specific factors. For example, with a debug hardware
341                          * unit the request is passed back to the host for execution.
342                          * This can lead to unpredictable delays in transmission and
343                          * process scheduling.
344                          *
345                          * Use this function to calculate time intervals, by calculating
346                          * differences between intervals with and without the code
347                          * sequence to be timed.
348                          *
349                          * Entry
350                          * The PARAMETER REGISTER must contain 0. There are no other
351                          * parameters.
352                          *
353                          * Return
354                          * On exit, the RETURN REGISTER contains:
355                          * - The number of centiseconds since some arbitrary start
356                          * point, if the call is successful.
357                          * - â€“1 if the call is not successful. For example, because
358                          * of a communications error.
359                          */
360                 {
361                         clock_t delta = clock() - semihosting->setup_time;
362
363                         semihosting->result = delta / (CLOCKS_PER_SEC / 100);
364                 }
365                 break;
366
367                 case SEMIHOSTING_SYS_CLOSE:     /* 0x02 */
368                         /*
369                          * Closes a file on the host system. The handle must reference
370                          * a file that was opened with SYS_OPEN.
371                          *
372                          * Entry
373                          * On entry, the PARAMETER REGISTER contains a pointer to a
374                          * one-field argument block:
375                          * - field 1 Contains a handle for an open file.
376                          *
377                          * Return
378                          * On exit, the RETURN REGISTER contains:
379                          * - 0 if the call is successful
380                          * - â€“1 if the call is not successful.
381                          */
382                         retval = semihosting_read_fields(target, 1, fields);
383                         if (retval != ERROR_OK)
384                                 return retval;
385                         else {
386                                 int fd = semihosting_get_field(target, 0, fields);
387                                 /* Do not allow to close OpenOCD's own standard streams */
388                                 if (fd == 0 || fd == 1 || fd == 2) {
389                                         LOG_DEBUG("ignoring semihosting attempt to close %s",
390                                                         (fd == 0) ? "stdin" :
391                                                         (fd == 1) ? "stdout" : "stderr");
392                                         /* Just pretend success */
393                                         if (semihosting->is_fileio) {
394                                                 semihosting->result = 0;
395                                         } else {
396                                                 semihosting->result = 0;
397                                                 semihosting->sys_errno = 0;
398                                         }
399                                         break;
400                                 }
401                                 /* Close the descriptor */
402                                 if (semihosting->is_fileio) {
403                                         semihosting->hit_fileio = true;
404                                         fileio_info->identifier = "close";
405                                         fileio_info->param_1 = fd;
406                                 } else {
407                                         semihosting->result = close(fd);
408                                         semihosting->sys_errno = errno;
409                                         LOG_DEBUG("close(%d)=%d", fd, (int)semihosting->result);
410                                 }
411                         }
412                         break;
413
414                 case SEMIHOSTING_SYS_ERRNO:     /* 0x13 */
415                         /*
416                          * Returns the value of the C library errno variable that is
417                          * associated with the semihosting implementation. The errno
418                          * variable can be set by a number of C library semihosted
419                          * functions, including:
420                          * - SYS_REMOVE
421                          * - SYS_OPEN
422                          * - SYS_CLOSE
423                          * - SYS_READ
424                          * - SYS_WRITE
425                          * - SYS_SEEK.
426                          *
427                          * Whether errno is set or not, and to what value, is entirely
428                          * host-specific, except where the ISO C standard defines the
429                          * behavior.
430                          *
431                          * Entry
432                          * There are no parameters. The PARAMETER REGISTER must be 0.
433                          *
434                          * Return
435                          * On exit, the RETURN REGISTER contains the value of the C
436                          * library errno variable.
437                          */
438                         semihosting->result = semihosting->sys_errno;
439                         break;
440
441                 case SEMIHOSTING_SYS_EXIT:      /* 0x18 */
442                         /*
443                          * Note: SYS_EXIT was called angel_SWIreason_ReportException in
444                          * previous versions of the documentation.
445                          *
446                          * An application calls this operation to report an exception
447                          * to the debugger directly. The most common use is to report
448                          * that execution has completed, using ADP_Stopped_ApplicationExit.
449                          *
450                          * Note: This semihosting operation provides no means for 32-bit
451                          * callers to indicate an application exit with a specified exit
452                          * code. Semihosting callers may prefer to check for the presence
453                          * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
454                          * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
455                          * is available.
456                          *
457                          * Entry (32-bit)
458                          * On entry, the PARAMETER register is set to a reason code
459                          * describing the cause of the trap. Not all semihosting client
460                          * implementations will necessarily trap every corresponding
461                          * event. Important reason codes are:
462                          *
463                          * - ADP_Stopped_ApplicationExit 0x20026
464                          * - ADP_Stopped_RunTimeErrorUnknown 0x20023
465                          *
466                          * Entry (64-bit)
467                          * On entry, the PARAMETER REGISTER contains a pointer to a
468                          * two-field argument block:
469                          * - field 1 The exception type, which is one of the set of
470                          * reason codes in the above tables.
471                          * - field 2 A subcode, whose meaning depends on the reason
472                          * code in field 1.
473                          * In particular, if field 1 is ADP_Stopped_ApplicationExit
474                          * then field 2 is an exit status code, as passed to the C
475                          * standard library exit() function. A simulator receiving
476                          * this request must notify a connected debugger, if present,
477                          * and then exit with the specified status.
478                          *
479                          * Return
480                          * No return is expected from these calls. However, it is
481                          * possible for the debugger to request that the application
482                          * continues by performing an RDI_Execute request or equivalent.
483                          * In this case, execution continues with the registers as they
484                          * were on entry to the operation, or as subsequently modified
485                          * by the debugger.
486                          */
487                         if (semihosting->word_size_bytes == 8) {
488                                 retval = semihosting_read_fields(target, 2, fields);
489                                 if (retval != ERROR_OK)
490                                         return retval;
491                                 else {
492                                         int type = semihosting_get_field(target, 0, fields);
493                                         int code = semihosting_get_field(target, 1, fields);
494
495                                         if (type == ADP_STOPPED_APPLICATION_EXIT) {
496                                                 if (!gdb_actual_connections)
497                                                         exit(code);
498                                                 else {
499                                                         fprintf(stderr,
500                                                                 "semihosting: *** application exited with %d ***\n",
501                                                                 code);
502                                                 }
503                                         } else {
504                                                 fprintf(stderr,
505                                                         "semihosting: application exception %#x\n",
506                                                         type);
507                                         }
508                                 }
509                         } else {
510                                 if (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {
511                                         if (!gdb_actual_connections)
512                                                 exit(0);
513                                         else {
514                                                 fprintf(stderr,
515                                                         "semihosting: *** application exited normally ***\n");
516                                         }
517                                 } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {
518                                         /* Chosen more or less arbitrarily to have a nicer message,
519                                          * otherwise all other return the same exit code 1. */
520                                         if (!gdb_actual_connections)
521                                                 exit(1);
522                                         else {
523                                                 fprintf(stderr,
524                                                         "semihosting: *** application exited with error ***\n");
525                                         }
526                                 } else {
527                                         if (!gdb_actual_connections)
528                                                 exit(1);
529                                         else {
530                                                 fprintf(stderr,
531                                                         "semihosting: application exception %#x\n",
532                                                         (unsigned) semihosting->param);
533                                         }
534                                 }
535                         }
536                         if (!semihosting->has_resumable_exit) {
537                                 semihosting->is_resumable = false;
538                                 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
539                         }
540                         break;
541
542                 case SEMIHOSTING_SYS_EXIT_EXTENDED:     /* 0x20 */
543                         /*
544                          * This operation is only supported if the semihosting extension
545                          * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
546                          * reported using feature byte 0, bit 0. If this extension is
547                          * supported, then the implementation provides a means to
548                          * report a normal exit with a nonzero exit status in both 32-bit
549                          * and 64-bit semihosting APIs.
550                          *
551                          * The implementation must provide the semihosting call
552                          * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
553                          *
554                          * SYS_EXIT_EXTENDED is used by an application to report an
555                          * exception or exit to the debugger directly. The most common
556                          * use is to report that execution has completed, using
557                          * ADP_Stopped_ApplicationExit.
558                          *
559                          * Entry
560                          * On entry, the PARAMETER REGISTER contains a pointer to a
561                          * two-field argument block:
562                          * - field 1 The exception type, which should be one of the set
563                          * of reason codes that are documented for the SYS_EXIT
564                          * (0x18) call. For example, ADP_Stopped_ApplicationExit.
565                          * - field 2 A subcode, whose meaning depends on the reason
566                          * code in field 1. In particular, if field 1 is
567                          * ADP_Stopped_ApplicationExit then field 2 is an exit status
568                          * code, as passed to the C standard library exit() function.
569                          * A simulator receiving this request must notify a connected
570                          * debugger, if present, and then exit with the specified status.
571                          *
572                          * Return
573                          * No return is expected from these calls.
574                          *
575                          * For the A64 API, this call is identical to the behavior of
576                          * the mandatory SYS_EXIT (0x18) call. If this extension is
577                          * supported, then both calls must be implemented.
578                          */
579                         retval = semihosting_read_fields(target, 2, fields);
580                         if (retval != ERROR_OK)
581                                 return retval;
582                         else {
583                                 int type = semihosting_get_field(target, 0, fields);
584                                 int code = semihosting_get_field(target, 1, fields);
585
586                                 if (type == ADP_STOPPED_APPLICATION_EXIT) {
587                                         if (!gdb_actual_connections)
588                                                 exit(code);
589                                         else {
590                                                 fprintf(stderr,
591                                                         "semihosting: *** application exited with %d ***\n",
592                                                         code);
593                                         }
594                                 } else {
595                                         fprintf(stderr, "semihosting: exception %#x\n",
596                                                 type);
597                                 }
598                         }
599                         if (!semihosting->has_resumable_exit) {
600                                 semihosting->is_resumable = false;
601                                 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
602                         }
603                         break;
604
605                 case SEMIHOSTING_SYS_FLEN:      /* 0x0C */
606                         /*
607                          * Returns the length of a specified file.
608                          *
609                          * Entry
610                          * On entry, the PARAMETER REGISTER contains a pointer to a
611                          * one-field argument block:
612                          * - field 1 A handle for a previously opened, seekable file
613                          * object.
614                          *
615                          * Return
616                          * On exit, the RETURN REGISTER contains:
617                          * - The current length of the file object, if the call is
618                          * successful.
619                          * - â€“1 if an error occurs.
620                          */
621                         if (semihosting->is_fileio) {
622                                 semihosting->result = -1;
623                                 semihosting->sys_errno = EINVAL;
624                         }
625                         retval = semihosting_read_fields(target, 1, fields);
626                         if (retval != ERROR_OK)
627                                 return retval;
628                         else {
629                                 int fd = semihosting_get_field(target, 0, fields);
630                                 struct stat buf;
631                                 semihosting->result = fstat(fd, &buf);
632                                 if (semihosting->result == -1) {
633                                         semihosting->sys_errno = errno;
634                                         LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
635                                         break;
636                                 }
637                                 LOG_DEBUG("fstat(%d)=%d", fd, (int)semihosting->result);
638                                 semihosting->result = buf.st_size;
639                         }
640                         break;
641
642                 case SEMIHOSTING_SYS_GET_CMDLINE:       /* 0x15 */
643                         /*
644                          * Returns the command line that is used for the call to the
645                          * executable, that is, argc and argv.
646                          *
647                          * Entry
648                          * On entry, the PARAMETER REGISTER points to a two-field data
649                          * block to be used for returning the command string and its length:
650                          * - field 1 A pointer to a buffer of at least the size that is
651                          * specified in field 2.
652                          * - field 2 The length of the buffer in bytes.
653                          *
654                          * Return
655                          * On exit:
656                          * If the call is successful, then the RETURN REGISTER contains 0,
657                          * the PARAMETER REGISTER is unchanged, and the data block is
658                          * updated as follows:
659                          * - field 1 A pointer to a null-terminated string of the command
660                          * line.
661                          * - field 2 The length of the string in bytes.
662                          * If the call is not successful, then the RETURN REGISTER
663                          * contains -1.
664                          *
665                          * Note: The semihosting implementation might impose limits on
666                          * the maximum length of the string that can be transferred.
667                          * However, the implementation must be able to support a
668                          * command-line length of at least 80 bytes.
669                          */
670                         retval = semihosting_read_fields(target, 2, fields);
671                         if (retval != ERROR_OK)
672                                 return retval;
673                         else {
674                                 uint64_t addr = semihosting_get_field(target, 0, fields);
675                                 size_t size = semihosting_get_field(target, 1, fields);
676
677                                 char *arg = semihosting->cmdline ?
678                                         semihosting->cmdline : "";
679                                 uint32_t len = strlen(arg) + 1;
680                                 if (len > size)
681                                         semihosting->result = -1;
682                                 else {
683                                         semihosting_set_field(target, len, 1, fields);
684                                         retval = target_write_buffer(target, addr, len,
685                                                         (uint8_t *)arg);
686                                         if (retval != ERROR_OK)
687                                                 return retval;
688                                         semihosting->result = 0;
689
690                                         retval = semihosting_write_fields(target, 2, fields);
691                                         if (retval != ERROR_OK)
692                                                 return retval;
693                                 }
694                                 LOG_DEBUG("SYS_GET_CMDLINE=[%s],%d", arg,
695                                         (int)semihosting->result);
696                         }
697                         break;
698
699                 case SEMIHOSTING_SYS_HEAPINFO:  /* 0x16 */
700                         /*
701                          * Returns the system stack and heap parameters.
702                          *
703                          * Entry
704                          * On entry, the PARAMETER REGISTER contains the address of a
705                          * pointer to a four-field data block. The contents of the data
706                          * block are filled by the function. The following C-like
707                          * pseudocode describes the layout of the block:
708                          * struct block {
709                          *   void* heap_base;
710                          *   void* heap_limit;
711                          *   void* stack_base;
712                          *   void* stack_limit;
713                          * };
714                          *
715                          * Return
716                          * On exit, the PARAMETER REGISTER is unchanged and the data
717                          * block has been updated.
718                          */
719                         retval = semihosting_read_fields(target, 1, fields);
720                         if (retval != ERROR_OK)
721                                 return retval;
722                         else {
723                                 uint64_t addr = semihosting_get_field(target, 0, fields);
724                                 /* tell the remote we have no idea */
725                                 memset(fields, 0, 4 * semihosting->word_size_bytes);
726                                 retval = target_write_memory(target, addr, 4,
727                                                 semihosting->word_size_bytes,
728                                                 fields);
729                                 if (retval != ERROR_OK)
730                                         return retval;
731                                 semihosting->result = 0;
732                         }
733                         break;
734
735                 case SEMIHOSTING_SYS_ISERROR:   /* 0x08 */
736                         /*
737                          * Determines whether the return code from another semihosting
738                          * call is an error status or not.
739                          *
740                          * This call is passed a parameter block containing the error
741                          * code to examine.
742                          *
743                          * Entry
744                          * On entry, the PARAMETER REGISTER contains a pointer to a
745                          * one-field data block:
746                          * - field 1 The required status word to check.
747                          *
748                          * Return
749                          * On exit, the RETURN REGISTER contains:
750                          * - 0 if the status field is not an error indication
751                          * - A nonzero value if the status field is an error indication.
752                          */
753                         retval = semihosting_read_fields(target, 1, fields);
754                         if (retval != ERROR_OK)
755                                 return retval;
756
757                         uint64_t code = semihosting_get_field(target, 0, fields);
758                         semihosting->result = (code != 0);
759                         break;
760
761                 case SEMIHOSTING_SYS_ISTTY:     /* 0x09 */
762                         /*
763                          * Checks whether a file is connected to an interactive device.
764                          *
765                          * Entry
766                          * On entry, the PARAMETER REGISTER contains a pointer to a
767                          * one-field argument block:
768                          * field 1 A handle for a previously opened file object.
769                          *
770                          * Return
771                          * On exit, the RETURN REGISTER contains:
772                          * - 1 if the handle identifies an interactive device.
773                          * - 0 if the handle identifies a file.
774                          * - A value other than 1 or 0 if an error occurs.
775                          */
776                         if (semihosting->is_fileio) {
777                                 semihosting->hit_fileio = true;
778                                 fileio_info->identifier = "isatty";
779                                 fileio_info->param_1 = semihosting->param;
780                         } else {
781                                 retval = semihosting_read_fields(target, 1, fields);
782                                 if (retval != ERROR_OK)
783                                         return retval;
784                                 int fd = semihosting_get_field(target, 0, fields);
785                                 semihosting->result = isatty(fd);
786                                 semihosting->sys_errno = errno;
787                                 LOG_DEBUG("isatty(%d)=%d", fd, (int)semihosting->result);
788                         }
789                         break;
790
791                 case SEMIHOSTING_SYS_OPEN:      /* 0x01 */
792                         /*
793                          * Opens a file on the host system.
794                          *
795                          * The file path is specified either as relative to the current
796                          * directory of the host process, or absolute, using the path
797                          * conventions of the host operating system.
798                          *
799                          * Semihosting implementations must support opening the special
800                          * path name :semihosting-features as part of the semihosting
801                          * extensions reporting mechanism.
802                          *
803                          * ARM targets interpret the special path name :tt as meaning
804                          * the console input stream, for an open-read or the console
805                          * output stream, for an open-write. Opening these streams is
806                          * performed as part of the standard startup code for those
807                          * applications that reference the C stdio streams. The
808                          * semihosting extension SH_EXT_STDOUT_STDERR allows the
809                          * semihosting caller to open separate output streams
810                          * corresponding to stdout and stderr. This extension is
811                          * reported using feature byte 0, bit 1. Use SYS_OPEN with
812                          * the special path name :semihosting-features to access the
813                          * feature bits.
814                          *
815                          * If this extension is supported, the implementation must
816                          * support the following additional semantics to SYS_OPEN:
817                          * - If the special path name :tt is opened with an fopen
818                          * mode requesting write access (w, wb, w+, or w+b), then
819                          * this is a request to open stdout.
820                          * - If the special path name :tt is opened with a mode
821                          * requesting append access (a, ab, a+, or a+b), then this is
822                          * a request to open stderr.
823                          *
824                          * Entry
825                          * On entry, the PARAMETER REGISTER contains a pointer to a
826                          * three-field argument block:
827                          * - field 1 A pointer to a null-terminated string containing
828                          * a file or device name.
829                          * - field 2 An integer that specifies the file opening mode.
830                          * - field 3 An integer that gives the length of the string
831                          * pointed to by field 1.
832                          *
833                          * The length does not include the terminating null character
834                          * that must be present.
835                          *
836                          * Return
837                          * On exit, the RETURN REGISTER contains:
838                          * - A nonzero handle if the call is successful.
839                          * - â€“1 if the call is not successful.
840                          */
841                         retval = semihosting_read_fields(target, 3, fields);
842                         if (retval != ERROR_OK)
843                                 return retval;
844                         else {
845                                 uint64_t addr = semihosting_get_field(target, 0, fields);
846                                 uint32_t mode = semihosting_get_field(target, 1, fields);
847                                 size_t len = semihosting_get_field(target, 2, fields);
848
849                                 if (mode > 11) {
850                                         semihosting->result = -1;
851                                         semihosting->sys_errno = EINVAL;
852                                         break;
853                                 }
854                                 size_t basedir_len = semihosting->basedir ? strlen(semihosting->basedir) : 0;
855                                 uint8_t *fn = malloc(basedir_len + len + 2);
856                                 if (!fn) {
857                                         semihosting->result = -1;
858                                         semihosting->sys_errno = ENOMEM;
859                                 } else {
860                                         if (basedir_len > 0) {
861                                                 strcpy((char *)fn, semihosting->basedir);
862                                                 if (fn[basedir_len - 1] != '/')
863                                                         fn[basedir_len++] = '/';
864                                         }
865                                         retval = target_read_memory(target, addr, 1, len, fn + basedir_len);
866                                         if (retval != ERROR_OK) {
867                                                 free(fn);
868                                                 return retval;
869                                         }
870                                         fn[basedir_len + len] = 0;
871                                         /* TODO: implement the :semihosting-features special file.
872                                          * */
873                                         if (semihosting->is_fileio) {
874                                                 if (strcmp((char *)fn, ":semihosting-features") == 0) {
875                                                         semihosting->result = -1;
876                                                         semihosting->sys_errno = EINVAL;
877                                                 } else if (strcmp((char *)fn, ":tt") == 0) {
878                                                         if (mode == 0)
879                                                                 semihosting->result = 0;
880                                                         else if (mode == 4)
881                                                                 semihosting->result = 1;
882                                                         else if (mode == 8)
883                                                                 semihosting->result = 2;
884                                                         else
885                                                                 semihosting->result = -1;
886                                                 } else {
887                                                         semihosting->hit_fileio = true;
888                                                         fileio_info->identifier = "open";
889                                                         fileio_info->param_1 = addr;
890                                                         fileio_info->param_2 = len;
891                                                         fileio_info->param_3 = open_gdb_modeflags[mode];
892                                                         fileio_info->param_4 = 0644;
893                                                 }
894                                         } else {
895                                                 if (strcmp((char *)fn, ":tt") == 0) {
896                                                         /* Mode is:
897                                                          * - 0-3 ("r") for stdin,
898                                                          * - 4-7 ("w") for stdout,
899                                                          * - 8-11 ("a") for stderr */
900                                                         if (mode < 4) {
901                                                                 int fd = dup(STDIN_FILENO);
902                                                                 semihosting->result = fd;
903                                                                 semihosting->stdin_fd = fd;
904                                                                 semihosting->sys_errno = errno;
905                                                                 LOG_DEBUG("dup(STDIN)=%d",
906                                                                         (int)semihosting->result);
907                                                         } else if (mode < 8) {
908                                                                 int fd = dup(STDOUT_FILENO);
909                                                                 semihosting->result = fd;
910                                                                 semihosting->stdout_fd = fd;
911                                                                 semihosting->sys_errno = errno;
912                                                                 LOG_DEBUG("dup(STDOUT)=%d",
913                                                                         (int)semihosting->result);
914                                                         } else {
915                                                                 int fd = dup(STDERR_FILENO);
916                                                                 semihosting->result = fd;
917                                                                 semihosting->stderr_fd = fd;
918                                                                 semihosting->sys_errno = errno;
919                                                                 LOG_DEBUG("dup(STDERR)=%d",
920                                                                         (int)semihosting->result);
921                                                         }
922                                                 } else {
923                                                         /* cygwin requires the permission setting
924                                                          * otherwise it will fail to reopen a previously
925                                                          * written file */
926                                                         semihosting->result = open((char *)fn,
927                                                                         open_host_modeflags[mode],
928                                                                         0644);
929                                                         semihosting->sys_errno = errno;
930                                                         LOG_DEBUG("open('%s')=%d", fn,
931                                                                 (int)semihosting->result);
932                                                 }
933                                         }
934                                         free(fn);
935                                 }
936                         }
937                         break;
938
939                 case SEMIHOSTING_SYS_READ:      /* 0x06 */
940                         /*
941                          * Reads the contents of a file into a buffer. The file position
942                          * is specified either:
943                          * - Explicitly by a SYS_SEEK.
944                          * - Implicitly one byte beyond the previous SYS_READ or
945                          * SYS_WRITE request.
946                          *
947                          * The file position is at the start of the file when it is
948                          * opened, and is lost when the file is closed. Perform the
949                          * file operation as a single action whenever possible. For
950                          * example, do not split a read of 16KB into four 4KB chunks
951                          * unless there is no alternative.
952                          *
953                          * Entry
954                          * On entry, the PARAMETER REGISTER contains a pointer to a
955                          * three-field data block:
956                          * - field 1 Contains a handle for a file previously opened
957                          * with SYS_OPEN.
958                          * - field 2 Points to a buffer.
959                          * - field 3 Contains the number of bytes to read to the buffer
960                          * from the file.
961                          *
962                          * Return
963                          * On exit, the RETURN REGISTER contains the number of bytes not
964                          * filled in the buffer (buffer_length - bytes_read) as follows:
965                          * - If the RETURN REGISTER is 0, the entire buffer was
966                          * successfully filled.
967                          * - If the RETURN REGISTER is the same as field 3, no bytes
968                          * were read (EOF can be assumed).
969                          * - If the RETURN REGISTER contains a value smaller than
970                          * field 3, the read succeeded but the buffer was only partly
971                          * filled. For interactive devices, this is the most common
972                          * return value.
973                          */
974                         retval = semihosting_read_fields(target, 3, fields);
975                         if (retval != ERROR_OK)
976                                 return retval;
977                         else {
978                                 int fd = semihosting_get_field(target, 0, fields);
979                                 uint64_t addr = semihosting_get_field(target, 1, fields);
980                                 size_t len = semihosting_get_field(target, 2, fields);
981                                 if (semihosting->is_fileio) {
982                                         semihosting->hit_fileio = true;
983                                         fileio_info->identifier = "read";
984                                         fileio_info->param_1 = fd;
985                                         fileio_info->param_2 = addr;
986                                         fileio_info->param_3 = len;
987                                 } else {
988                                         uint8_t *buf = malloc(len);
989                                         if (!buf) {
990                                                 semihosting->result = -1;
991                                                 semihosting->sys_errno = ENOMEM;
992                                         } else {
993                                                 semihosting->result = semihosting_read(semihosting, fd, buf, len);
994                                                 LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
995                                                         fd,
996                                                         addr,
997                                                         len,
998                                                         (int)semihosting->result);
999                                                 if (semihosting->result >= 0) {
1000                                                         retval = target_write_buffer(target, addr,
1001                                                                         semihosting->result,
1002                                                                         buf);
1003                                                         if (retval != ERROR_OK) {
1004                                                                 free(buf);
1005                                                                 return retval;
1006                                                         }
1007                                                         /* the number of bytes NOT filled in */
1008                                                         semihosting->result = len -
1009                                                                 semihosting->result;
1010                                                 }
1011                                                 free(buf);
1012                                         }
1013                                 }
1014                         }
1015                         break;
1016
1017                 case SEMIHOSTING_SYS_READC:     /* 0x07 */
1018                         /*
1019                          * Reads a byte from the console.
1020                          *
1021                          * Entry
1022                          * The PARAMETER REGISTER must contain 0. There are no other
1023                          * parameters or values possible.
1024                          *
1025                          * Return
1026                          * On exit, the RETURN REGISTER contains the byte read from
1027                          * the console.
1028                          */
1029                         if (semihosting->is_fileio) {
1030                                 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1031                                 return ERROR_FAIL;
1032                         }
1033                         semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);
1034                         LOG_DEBUG("getchar()=%d", (int)semihosting->result);
1035                         break;
1036
1037                 case SEMIHOSTING_SYS_REMOVE:    /* 0x0E */
1038                         /*
1039                          * Deletes a specified file on the host filing system.
1040                          *
1041                          * Entry
1042                          * On entry, the PARAMETER REGISTER contains a pointer to a
1043                          * two-field argument block:
1044                          * - field 1 Points to a null-terminated string that gives the
1045                          * path name of the file to be deleted.
1046                          * - field 2 The length of the string.
1047                          *
1048                          * Return
1049                          * On exit, the RETURN REGISTER contains:
1050                          * - 0 if the delete is successful
1051                          * - A nonzero, host-specific error code if the delete fails.
1052                          */
1053                         retval = semihosting_read_fields(target, 2, fields);
1054                         if (retval != ERROR_OK)
1055                                 return retval;
1056                         else {
1057                                 uint64_t addr = semihosting_get_field(target, 0, fields);
1058                                 size_t len = semihosting_get_field(target, 1, fields);
1059                                 if (semihosting->is_fileio) {
1060                                         semihosting->hit_fileio = true;
1061                                         fileio_info->identifier = "unlink";
1062                                         fileio_info->param_1 = addr;
1063                                         fileio_info->param_2 = len;
1064                                 } else {
1065                                         uint8_t *fn = malloc(len+1);
1066                                         if (!fn) {
1067                                                 semihosting->result = -1;
1068                                                 semihosting->sys_errno = ENOMEM;
1069                                         } else {
1070                                                 retval =
1071                                                         target_read_memory(target, addr, 1, len,
1072                                                                 fn);
1073                                                 if (retval != ERROR_OK) {
1074                                                         free(fn);
1075                                                         return retval;
1076                                                 }
1077                                                 fn[len] = 0;
1078                                                 semihosting->result = remove((char *)fn);
1079                                                 semihosting->sys_errno = errno;
1080                                                 LOG_DEBUG("remove('%s')=%d", fn,
1081                                                         (int)semihosting->result);
1082
1083                                                 free(fn);
1084                                         }
1085                                 }
1086                         }
1087                         break;
1088
1089                 case SEMIHOSTING_SYS_RENAME:    /* 0x0F */
1090                         /*
1091                          * Renames a specified file.
1092                          *
1093                          * Entry
1094                          * On entry, the PARAMETER REGISTER contains a pointer to a
1095                          * four-field data block:
1096                          * - field 1 A pointer to the name of the old file.
1097                          * - field 2 The length of the old filename.
1098                          * - field 3 A pointer to the new filename.
1099                          * - field 4 The length of the new filename. Both strings are
1100                          * null-terminated.
1101                          *
1102                          * Return
1103                          * On exit, the RETURN REGISTER contains:
1104                          * - 0 if the rename is successful.
1105                          * - A nonzero, host-specific error code if the rename fails.
1106                          */
1107                         retval = semihosting_read_fields(target, 4, fields);
1108                         if (retval != ERROR_OK)
1109                                 return retval;
1110                         else {
1111                                 uint64_t addr1 = semihosting_get_field(target, 0, fields);
1112                                 size_t len1 = semihosting_get_field(target, 1, fields);
1113                                 uint64_t addr2 = semihosting_get_field(target, 2, fields);
1114                                 size_t len2 = semihosting_get_field(target, 3, fields);
1115                                 if (semihosting->is_fileio) {
1116                                         semihosting->hit_fileio = true;
1117                                         fileio_info->identifier = "rename";
1118                                         fileio_info->param_1 = addr1;
1119                                         fileio_info->param_2 = len1;
1120                                         fileio_info->param_3 = addr2;
1121                                         fileio_info->param_4 = len2;
1122                                 } else {
1123                                         uint8_t *fn1 = malloc(len1+1);
1124                                         uint8_t *fn2 = malloc(len2+1);
1125                                         if (!fn1 || !fn2) {
1126                                                 free(fn1);
1127                                                 free(fn2);
1128                                                 semihosting->result = -1;
1129                                                 semihosting->sys_errno = ENOMEM;
1130                                         } else {
1131                                                 retval = target_read_memory(target, addr1, 1, len1,
1132                                                                 fn1);
1133                                                 if (retval != ERROR_OK) {
1134                                                         free(fn1);
1135                                                         free(fn2);
1136                                                         return retval;
1137                                                 }
1138                                                 retval = target_read_memory(target, addr2, 1, len2,
1139                                                                 fn2);
1140                                                 if (retval != ERROR_OK) {
1141                                                         free(fn1);
1142                                                         free(fn2);
1143                                                         return retval;
1144                                                 }
1145                                                 fn1[len1] = 0;
1146                                                 fn2[len2] = 0;
1147                                                 semihosting->result = rename((char *)fn1,
1148                                                                 (char *)fn2);
1149                                                 semihosting->sys_errno = errno;
1150                                                 LOG_DEBUG("rename('%s', '%s')=%d", fn1, fn2,
1151                                                         (int)semihosting->result);
1152
1153                                                 free(fn1);
1154                                                 free(fn2);
1155                                         }
1156                                 }
1157                         }
1158                         break;
1159
1160                 case SEMIHOSTING_SYS_SEEK:      /* 0x0A */
1161                         /*
1162                          * Seeks to a specified position in a file using an offset
1163                          * specified from the start of the file. The file is assumed
1164                          * to be a byte array and the offset is given in bytes.
1165                          *
1166                          * Entry
1167                          * On entry, the PARAMETER REGISTER contains a pointer to a
1168                          * two-field data block:
1169                          * - field 1 A handle for a seekable file object.
1170                          * - field 2 The absolute byte position to seek to.
1171                          *
1172                          * Return
1173                          * On exit, the RETURN REGISTER contains:
1174                          * - 0 if the request is successful.
1175                          * - A negative value if the request is not successful.
1176                          * Use SYS_ERRNO to read the value of the host errno variable
1177                          * describing the error.
1178                          *
1179                          * Note: The effect of seeking outside the current extent of
1180                          * the file object is undefined.
1181                          */
1182                         retval = semihosting_read_fields(target, 2, fields);
1183                         if (retval != ERROR_OK)
1184                                 return retval;
1185                         else {
1186                                 int fd = semihosting_get_field(target, 0, fields);
1187                                 off_t pos = semihosting_get_field(target, 1, fields);
1188                                 if (semihosting->is_fileio) {
1189                                         semihosting->hit_fileio = true;
1190                                         fileio_info->identifier = "lseek";
1191                                         fileio_info->param_1 = fd;
1192                                         fileio_info->param_2 = pos;
1193                                         fileio_info->param_3 = SEEK_SET;
1194                                 } else {
1195                                         semihosting->result = lseek(fd, pos, SEEK_SET);
1196                                         semihosting->sys_errno = errno;
1197                                         LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos,
1198                                                 (int)semihosting->result);
1199                                         if (semihosting->result == pos)
1200                                                 semihosting->result = 0;
1201                                 }
1202                         }
1203                         break;
1204
1205                 case SEMIHOSTING_SYS_SYSTEM:    /* 0x12 */
1206                         /*
1207                          * Passes a command to the host command-line interpreter.
1208                          * This enables you to execute a system command such as dir,
1209                          * ls, or pwd. The terminal I/O is on the host, and is not
1210                          * visible to the target.
1211                          *
1212                          * Entry
1213                          * On entry, the PARAMETER REGISTER contains a pointer to a
1214                          * two-field argument block:
1215                          * - field 1 Points to a string to be passed to the host
1216                          * command-line interpreter.
1217                          * - field 2 The length of the string.
1218                          *
1219                          * Return
1220                          * On exit, the RETURN REGISTER contains the return status.
1221                          */
1222
1223                         /* Provide SYS_SYSTEM functionality.  Uses the
1224                          * libc system command, there may be a reason *NOT*
1225                          * to use this, but as I can't think of one, I
1226                          * implemented it this way.
1227                          */
1228                         retval = semihosting_read_fields(target, 2, fields);
1229                         if (retval != ERROR_OK)
1230                                 return retval;
1231                         else {
1232                                 uint64_t addr = semihosting_get_field(target, 0, fields);
1233                                 size_t len = semihosting_get_field(target, 1, fields);
1234                                 if (semihosting->is_fileio) {
1235                                         semihosting->hit_fileio = true;
1236                                         fileio_info->identifier = "system";
1237                                         fileio_info->param_1 = addr;
1238                                         fileio_info->param_2 = len;
1239                                 } else {
1240                                         uint8_t *cmd = malloc(len+1);
1241                                         if (!cmd) {
1242                                                 semihosting->result = -1;
1243                                                 semihosting->sys_errno = ENOMEM;
1244                                         } else {
1245                                                 retval = target_read_memory(target,
1246                                                                 addr,
1247                                                                 1,
1248                                                                 len,
1249                                                                 cmd);
1250                                                 if (retval != ERROR_OK) {
1251                                                         free(cmd);
1252                                                         return retval;
1253                                                 } else {
1254                                                         cmd[len] = 0;
1255                                                         semihosting->result = system(
1256                                                                         (const char *)cmd);
1257                                                         LOG_DEBUG("system('%s')=%d",
1258                                                                 cmd,
1259                                                                 (int)semihosting->result);
1260                                                 }
1261
1262                                                 free(cmd);
1263                                         }
1264                                 }
1265                         }
1266                         break;
1267
1268                 case SEMIHOSTING_SYS_TIME:      /* 0x11 */
1269                         /*
1270                          * Returns the number of seconds since 00:00 January 1, 1970.
1271                          * This value is real-world time, regardless of any debug agent
1272                          * configuration.
1273                          *
1274                          * Entry
1275                          * There are no parameters.
1276                          *
1277                          * Return
1278                          * On exit, the RETURN REGISTER contains the number of seconds.
1279                          */
1280                         semihosting->result = time(NULL);
1281                         break;
1282
1283                 case SEMIHOSTING_SYS_WRITE:     /* 0x05 */
1284                         /*
1285                          * Writes the contents of a buffer to a specified file at the
1286                          * current file position. The file position is specified either:
1287                          * - Explicitly, by a SYS_SEEK.
1288                          * - Implicitly as one byte beyond the previous SYS_READ or
1289                          * SYS_WRITE request.
1290                          *
1291                          * The file position is at the start of the file when the file
1292                          * is opened, and is lost when the file is closed.
1293                          *
1294                          * Perform the file operation as a single action whenever
1295                          * possible. For example, do not split a write of 16KB into
1296                          * four 4KB chunks unless there is no alternative.
1297                          *
1298                          * Entry
1299                          * On entry, the PARAMETER REGISTER contains a pointer to a
1300                          * three-field data block:
1301                          * - field 1 Contains a handle for a file previously opened
1302                          * with SYS_OPEN.
1303                          * - field 2 Points to the memory containing the data to be written.
1304                          * - field 3 Contains the number of bytes to be written from
1305                          * the buffer to the file.
1306                          *
1307                          * Return
1308                          * On exit, the RETURN REGISTER contains:
1309                          * - 0 if the call is successful.
1310                          * - The number of bytes that are not written, if there is an error.
1311                          */
1312                         retval = semihosting_read_fields(target, 3, fields);
1313                         if (retval != ERROR_OK)
1314                                 return retval;
1315                         else {
1316                                 int fd = semihosting_get_field(target, 0, fields);
1317                                 uint64_t addr = semihosting_get_field(target, 1, fields);
1318                                 size_t len = semihosting_get_field(target, 2, fields);
1319                                 if (semihosting->is_fileio) {
1320                                         semihosting->hit_fileio = true;
1321                                         fileio_info->identifier = "write";
1322                                         fileio_info->param_1 = fd;
1323                                         fileio_info->param_2 = addr;
1324                                         fileio_info->param_3 = len;
1325                                 } else {
1326                                         uint8_t *buf = malloc(len);
1327                                         if (!buf) {
1328                                                 semihosting->result = -1;
1329                                                 semihosting->sys_errno = ENOMEM;
1330                                         } else {
1331                                                 retval = target_read_buffer(target, addr, len, buf);
1332                                                 if (retval != ERROR_OK) {
1333                                                         free(buf);
1334                                                         return retval;
1335                                                 }
1336                                                 semihosting->result = semihosting_write(semihosting, fd, buf, len);
1337                                                 semihosting->sys_errno = errno;
1338                                                 LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
1339                                                         fd,
1340                                                         addr,
1341                                                         len,
1342                                                         (int)semihosting->result);
1343                                                 if (semihosting->result >= 0) {
1344                                                         /* The number of bytes that are NOT written.
1345                                                          * */
1346                                                         semihosting->result = len -
1347                                                                 semihosting->result;
1348                                                 }
1349
1350                                                 free(buf);
1351                                         }
1352                                 }
1353                         }
1354                         break;
1355
1356                 case SEMIHOSTING_SYS_WRITEC:    /* 0x03 */
1357                         /*
1358                          * Writes a character byte, pointed to by the PARAMETER REGISTER,
1359                          * to the debug channel. When executed under a semihosting
1360                          * debugger, the character appears on the host debugger console.
1361                          *
1362                          * Entry
1363                          * On entry, the PARAMETER REGISTER contains a pointer to the
1364                          * character.
1365                          *
1366                          * Return
1367                          * None. The RETURN REGISTER is corrupted.
1368                          */
1369                         if (semihosting->is_fileio) {
1370                                 semihosting->hit_fileio = true;
1371                                 fileio_info->identifier = "write";
1372                                 fileio_info->param_1 = 1;
1373                                 fileio_info->param_2 = semihosting->param;
1374                                 fileio_info->param_3 = 1;
1375                         } else {
1376                                 uint64_t addr = semihosting->param;
1377                                 unsigned char c;
1378                                 retval = target_read_memory(target, addr, 1, 1, &c);
1379                                 if (retval != ERROR_OK)
1380                                         return retval;
1381                                 semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1382                                 semihosting->result = 0;
1383                         }
1384                         break;
1385
1386                 case SEMIHOSTING_SYS_WRITE0:    /* 0x04 */
1387                         /*
1388                          * Writes a null-terminated string to the debug channel.
1389                          * When executed under a semihosting debugger, the characters
1390                          * appear on the host debugger console.
1391                          *
1392                          * Entry
1393                          * On entry, the PARAMETER REGISTER contains a pointer to the
1394                          * first byte of the string.
1395                          *
1396                          * Return
1397                          * None. The RETURN REGISTER is corrupted.
1398                          */
1399                         if (semihosting->is_fileio) {
1400                                 size_t count = 0;
1401                                 uint64_t addr = semihosting->param;
1402                                 for (;; addr++) {
1403                                         unsigned char c;
1404                                         retval = target_read_memory(target, addr, 1, 1, &c);
1405                                         if (retval != ERROR_OK)
1406                                                 return retval;
1407                                         if (c == '\0')
1408                                                 break;
1409                                         count++;
1410                                 }
1411                                 semihosting->hit_fileio = true;
1412                                 fileio_info->identifier = "write";
1413                                 fileio_info->param_1 = 1;
1414                                 fileio_info->param_2 = semihosting->param;
1415                                 fileio_info->param_3 = count;
1416                         } else {
1417                                 uint64_t addr = semihosting->param;
1418                                 do {
1419                                         unsigned char c;
1420                                         retval = target_read_memory(target, addr++, 1, 1, &c);
1421                                         if (retval != ERROR_OK)
1422                                                 return retval;
1423                                         if (!c)
1424                                                 break;
1425                                         semihosting_putchar(semihosting, semihosting->stdout_fd, c);
1426                                 } while (1);
1427                                 semihosting->result = 0;
1428                         }
1429                         break;
1430
1431                 case SEMIHOSTING_USER_CMD_0x100 ... SEMIHOSTING_USER_CMD_0x107:
1432                         /**
1433                          * This is a user defined operation (while user cmds 0x100-0x1ff
1434                          * are possible, only 0x100-0x107 are currently implemented).
1435                          *
1436                          * Reads the user operation parameters from target, then fires the
1437                          * corresponding target event. When the target callbacks returned,
1438                          * cleans up the command parameter buffer.
1439                          *
1440                          * Entry
1441                          * On entry, the PARAMETER REGISTER contains a pointer to a
1442                          * two-field data block:
1443                          * - field 1 Contains a pointer to the bound command parameter
1444                          * string
1445                          * - field 2 Contains the command parameter string length
1446                          *
1447                          * Return
1448                          * On exit, the RETURN REGISTER contains the return status.
1449                          */
1450                         if (semihosting->user_command_extension) {
1451                                 retval = semihosting->user_command_extension(target);
1452                                 if (retval != ERROR_NOT_IMPLEMENTED)
1453                                         break;
1454                                 /* If custom user command not handled, we are looking for the TCL handler */
1455                         }
1456
1457                         assert(!semihosting_user_op_params);
1458                         retval = semihosting_read_fields(target, 2, fields);
1459                         if (retval != ERROR_OK) {
1460                                 LOG_ERROR("Failed to read fields for user defined command"
1461                                                 " op=0x%x", semihosting->op);
1462                                 return retval;
1463                         }
1464
1465                         uint64_t addr = semihosting_get_field(target, 0, fields);
1466
1467                         size_t len = semihosting_get_field(target, 1, fields);
1468                         if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
1469                                 LOG_ERROR("The maximum length for user defined command "
1470                                                 "parameter is %u, received length is %zu (op=0x%x)",
1471                                                 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
1472                                                 len,
1473                                                 semihosting->op);
1474                                 return ERROR_FAIL;
1475                         }
1476
1477                         semihosting_user_op_params = malloc(len + 1);
1478                         if (!semihosting_user_op_params)
1479                                 return ERROR_FAIL;
1480                         semihosting_user_op_params[len] = 0;
1481
1482                         retval = target_read_buffer(target, addr, len,
1483                                         (uint8_t *)(semihosting_user_op_params));
1484                         if (retval != ERROR_OK) {
1485                                 LOG_ERROR("Failed to read from target, semihosting op=0x%x",
1486                                                 semihosting->op);
1487                                 free(semihosting_user_op_params);
1488                                 semihosting_user_op_params = NULL;
1489                                 return retval;
1490                         }
1491
1492                         target_handle_event(target, semihosting->op);
1493                         free(semihosting_user_op_params);
1494                         semihosting_user_op_params = NULL;
1495                         semihosting->result = 0;
1496                         break;
1497
1498                 case SEMIHOSTING_SYS_ELAPSED:   /* 0x30 */
1499                 /*
1500                  * Returns the number of elapsed target ticks since execution
1501                  * started.
1502                  * Use SYS_TICKFREQ to determine the tick frequency.
1503                  *
1504                  * Entry (32-bit)
1505                  * On entry, the PARAMETER REGISTER points to a two-field data
1506                  * block to be used for returning the number of elapsed ticks:
1507                  * - field 1 The least significant field and is at the low address.
1508                  * - field 2 The most significant field and is at the high address.
1509                  *
1510                  * Entry (64-bit)
1511                  * On entry the PARAMETER REGISTER points to a one-field data
1512                  * block to be used for returning the number of elapsed ticks:
1513                  * - field 1 The number of elapsed ticks as a 64-bit value.
1514                  *
1515                  * Return
1516                  * On exit:
1517                  * - On success, the RETURN REGISTER contains 0, the PARAMETER
1518                  * REGISTER is unchanged, and the data block pointed to by the
1519                  * PARAMETER REGISTER is filled in with the number of elapsed
1520                  * ticks.
1521                  * - On failure, the RETURN REGISTER contains -1, and the
1522                  * PARAMETER REGISTER contains -1.
1523                  *
1524                  * Note: Some semihosting implementations might not support this
1525                  * semihosting operation, and they always return -1 in the
1526                  * RETURN REGISTER.
1527                  */
1528
1529                 case SEMIHOSTING_SYS_TICKFREQ:  /* 0x31 */
1530                 /*
1531                  * Returns the tick frequency.
1532                  *
1533                  * Entry
1534                  * The PARAMETER REGISTER must contain 0 on entry to this routine.
1535                  *
1536                  * Return
1537                  * On exit, the RETURN REGISTER contains either:
1538                  * - The number of ticks per second.
1539                  * - â€“1 if the target does not know the value of one tick.
1540                  *
1541                  * Note: Some semihosting implementations might not support
1542                  * this semihosting operation, and they always return -1 in the
1543                  * RETURN REGISTER.
1544                  */
1545
1546                 case SEMIHOSTING_SYS_TMPNAM:    /* 0x0D */
1547                 /*
1548                  * Returns a temporary name for a file identified by a system
1549                  * file identifier.
1550                  *
1551                  * Entry
1552                  * On entry, the PARAMETER REGISTER contains a pointer to a
1553                  * three-word argument block:
1554                  * - field 1 A pointer to a buffer.
1555                  * - field 2 A target identifier for this filename. Its value
1556                  * must be an integer in the range 0-255.
1557                  * - field 3 Contains the length of the buffer. The length must
1558                  * be at least the value of L_tmpnam on the host system.
1559                  *
1560                  * Return
1561                  * On exit, the RETURN REGISTER contains:
1562                  * - 0 if the call is successful.
1563                  * - â€“1 if an error occurs.
1564                  *
1565                  * The buffer pointed to by the PARAMETER REGISTER contains
1566                  * the filename, prefixed with a suitable directory name.
1567                  * If you use the same target identifier again, the same
1568                  * filename is returned.
1569                  *
1570                  * Note: The returned string must be null-terminated.
1571                  */
1572
1573                 default:
1574                         fprintf(stderr, "semihosting: unsupported call %#x\n",
1575                                 (unsigned) semihosting->op);
1576                         semihosting->result = -1;
1577                         semihosting->sys_errno = ENOTSUP;
1578         }
1579
1580         if (!semihosting->hit_fileio) {
1581                 retval = semihosting->post_result(target);
1582                 if (retval != ERROR_OK) {
1583                         LOG_ERROR("Failed to post semihosting result");
1584                         return retval;
1585                 }
1586         }
1587
1588         return ERROR_OK;
1589 }
1590
1591 /* -------------------------------------------------------------------------
1592  * Local functions. */
1593
1594 static int semihosting_common_fileio_info(struct target *target,
1595         struct gdb_fileio_info *fileio_info)
1596 {
1597         struct semihosting *semihosting = target->semihosting;
1598         if (!semihosting)
1599                 return ERROR_FAIL;
1600
1601         /*
1602          * To avoid unnecessary duplication, semihosting prepares the
1603          * fileio_info structure out-of-band when the target halts. See
1604          * do_semihosting for more detail.
1605          */
1606         if (!semihosting->is_fileio || !semihosting->hit_fileio)
1607                 return ERROR_FAIL;
1608
1609         return ERROR_OK;
1610 }
1611
1612 static int semihosting_common_fileio_end(struct target *target, int result,
1613         int fileio_errno, bool ctrl_c)
1614 {
1615         struct gdb_fileio_info *fileio_info = target->fileio_info;
1616         struct semihosting *semihosting = target->semihosting;
1617         if (!semihosting)
1618                 return ERROR_FAIL;
1619
1620         /* clear pending status */
1621         semihosting->hit_fileio = false;
1622
1623         semihosting->result = result;
1624         semihosting->sys_errno = fileio_errno;
1625
1626         /*
1627          * Some fileio results do not match up with what the semihosting
1628          * operation expects; for these operations, we munge the results
1629          * below:
1630          */
1631         switch (semihosting->op) {
1632                 case SEMIHOSTING_SYS_WRITE:     /* 0x05 */
1633                 case SEMIHOSTING_SYS_READ:      /* 0x06 */
1634                         if (result < 0)
1635                                 semihosting->result = fileio_info->param_3;  /* Zero bytes read/written. */
1636                         else
1637                                 semihosting->result = (int64_t)fileio_info->param_3 - result;
1638                         break;
1639
1640                 case SEMIHOSTING_SYS_SEEK:      /* 0x0a */
1641                         if (result > 0)
1642                                 semihosting->result = 0;
1643                         break;
1644         }
1645
1646         return semihosting->post_result(target);
1647 }
1648
1649 /* -------------------------------------------------------------------------
1650  * Utility functions. */
1651
1652 /**
1653  * Read all fields of a command from target to buffer.
1654  */
1655 int semihosting_read_fields(struct target *target, size_t number,
1656         uint8_t *fields)
1657 {
1658         struct semihosting *semihosting = target->semihosting;
1659         /* Use 4-byte multiples to trigger fast memory access. */
1660         return target_read_memory(target, semihosting->param, 4,
1661                         number * (semihosting->word_size_bytes / 4), fields);
1662 }
1663
1664 /**
1665  * Write all fields of a command from buffer to target.
1666  */
1667 int semihosting_write_fields(struct target *target, size_t number,
1668         uint8_t *fields)
1669 {
1670         struct semihosting *semihosting = target->semihosting;
1671         /* Use 4-byte multiples to trigger fast memory access. */
1672         return target_write_memory(target, semihosting->param, 4,
1673                         number * (semihosting->word_size_bytes / 4), fields);
1674 }
1675
1676 /**
1677  * Extract a field from the buffer, considering register size and endianness.
1678  */
1679 uint64_t semihosting_get_field(struct target *target, size_t index,
1680         uint8_t *fields)
1681 {
1682         struct semihosting *semihosting = target->semihosting;
1683         if (semihosting->word_size_bytes == 8)
1684                 return target_buffer_get_u64(target, fields + (index * 8));
1685         else
1686                 return target_buffer_get_u32(target, fields + (index * 4));
1687 }
1688
1689 /**
1690  * Store a field in the buffer, considering register size and endianness.
1691  */
1692 void semihosting_set_field(struct target *target, uint64_t value,
1693         size_t index,
1694         uint8_t *fields)
1695 {
1696         struct semihosting *semihosting = target->semihosting;
1697         if (semihosting->word_size_bytes == 8)
1698                 target_buffer_set_u64(target, fields + (index * 8), value);
1699         else
1700                 target_buffer_set_u32(target, fields + (index * 4), value);
1701 }
1702
1703 /* -------------------------------------------------------------------------
1704  * Semihosting redirect over TCP structs and functions */
1705
1706 static int semihosting_service_new_connection_handler(struct connection *connection)
1707 {
1708         struct semihosting_tcp_service *service = connection->service->priv;
1709         service->semihosting->tcp_connection = connection;
1710
1711         return ERROR_OK;
1712 }
1713
1714 static int semihosting_service_input_handler(struct connection *connection)
1715 {
1716         struct semihosting_tcp_service *service = connection->service->priv;
1717
1718         if (!connection->input_pending) {
1719                 /* consume received data, not for semihosting IO */
1720                 const int buf_len = 100;
1721                 char buf[buf_len];
1722                 int bytes_read = connection_read(connection, buf, buf_len);
1723
1724                 if (bytes_read == 0) {
1725                         return ERROR_SERVER_REMOTE_CLOSED;
1726                 } else if (bytes_read == -1) {
1727                         LOG_ERROR("error during read: %s", strerror(errno));
1728                         return ERROR_SERVER_REMOTE_CLOSED;
1729                 }
1730         } else if (service->error != ERROR_OK) {
1731                 return ERROR_SERVER_REMOTE_CLOSED;
1732         }
1733
1734         return ERROR_OK;
1735 }
1736
1737 static int semihosting_service_connection_closed_handler(struct connection *connection)
1738 {
1739         struct semihosting_tcp_service *service = connection->service->priv;
1740         if (service) {
1741                 free(service->name);
1742                 free(service);
1743         }
1744
1745         return ERROR_OK;
1746 }
1747
1748 static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
1749 {
1750         if (!semihosting->tcp_connection)
1751                 return;
1752
1753         struct service *service = semihosting->tcp_connection->service;
1754         remove_service(service->name, service->port);
1755         semihosting->tcp_connection = NULL;
1756
1757 }
1758
1759 static const struct service_driver semihosting_service_driver = {
1760         .name = "semihosting",
1761         .new_connection_during_keep_alive_handler = NULL,
1762         .new_connection_handler = semihosting_service_new_connection_handler,
1763         .input_handler = semihosting_service_input_handler,
1764         .connection_closed_handler = semihosting_service_connection_closed_handler,
1765         .keep_client_alive_handler = NULL,
1766 };
1767
1768 /* -------------------------------------------------------------------------
1769  * Common semihosting commands handlers. */
1770
1771 COMMAND_HANDLER(handle_common_semihosting_command)
1772 {
1773         struct target *target = get_current_target(CMD_CTX);
1774
1775         if (!target) {
1776                 LOG_ERROR("No target selected");
1777                 return ERROR_FAIL;
1778         }
1779
1780         struct semihosting *semihosting = target->semihosting;
1781         if (!semihosting) {
1782                 command_print(CMD, "semihosting not supported for current target");
1783                 return ERROR_FAIL;
1784         }
1785
1786         if (CMD_ARGC > 0) {
1787                 int is_active;
1788
1789                 COMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);
1790
1791                 if (!target_was_examined(target)) {
1792                         LOG_ERROR("Target not examined yet");
1793                         return ERROR_FAIL;
1794                 }
1795
1796                 if (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {
1797                         LOG_ERROR("Failed to Configure semihosting");
1798                         return ERROR_FAIL;
1799                 }
1800
1801                 /* FIXME never let that "catch" be dropped! (???) */
1802                 semihosting->is_active = is_active;
1803         }
1804
1805         command_print(CMD, "semihosting is %s",
1806                 semihosting->is_active
1807                 ? "enabled" : "disabled");
1808
1809         return ERROR_OK;
1810 }
1811
1812 COMMAND_HANDLER(handle_common_semihosting_redirect_command)
1813 {
1814         struct target *target = get_current_target(CMD_CTX);
1815
1816         if (!target) {
1817                 LOG_ERROR("No target selected");
1818                 return ERROR_FAIL;
1819         }
1820
1821         struct semihosting *semihosting = target->semihosting;
1822         if (!semihosting) {
1823                 command_print(CMD, "semihosting not supported for current target");
1824                 return ERROR_FAIL;
1825         }
1826
1827         if (!semihosting->is_active) {
1828                 command_print(CMD, "semihosting not yet enabled for current target");
1829                 return ERROR_FAIL;
1830         }
1831
1832         enum semihosting_redirect_config cfg;
1833         const char *port;
1834
1835         if (CMD_ARGC < 1)
1836                 return ERROR_COMMAND_SYNTAX_ERROR;
1837
1838         if (strcmp(CMD_ARGV[0], "disable") == 0) {
1839                 cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1840                 if (CMD_ARGC > 1)
1841                         return ERROR_COMMAND_SYNTAX_ERROR;
1842         } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
1843                 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1844                         return ERROR_COMMAND_SYNTAX_ERROR;
1845
1846                 port = CMD_ARGV[1];
1847
1848                 cfg = SEMIHOSTING_REDIRECT_CFG_ALL;
1849                 if (CMD_ARGC == 3) {
1850                         if (strcmp(CMD_ARGV[2], "debug") == 0)
1851                                 cfg = SEMIHOSTING_REDIRECT_CFG_DEBUG;
1852                         else if (strcmp(CMD_ARGV[2], "stdio") == 0)
1853                                 cfg = SEMIHOSTING_REDIRECT_CFG_STDIO;
1854                         else if (strcmp(CMD_ARGV[2], "all") != 0)
1855                                 return ERROR_COMMAND_SYNTAX_ERROR;
1856                 }
1857         } else {
1858                 return ERROR_COMMAND_SYNTAX_ERROR;
1859         }
1860
1861         semihosting_tcp_close_cnx(semihosting);
1862         semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
1863
1864         if (cfg != SEMIHOSTING_REDIRECT_CFG_NONE) {
1865                 struct semihosting_tcp_service *service =
1866                                 calloc(1, sizeof(struct semihosting_tcp_service));
1867                 if (!service) {
1868                         LOG_ERROR("Failed to allocate semihosting TCP service.");
1869                         return ERROR_FAIL;
1870                 }
1871
1872                 service->semihosting = semihosting;
1873
1874                 service->name = alloc_printf("%s semihosting service", target_name(target));
1875                 if (!service->name) {
1876                         LOG_ERROR("Out of memory");
1877                         free(service);
1878                         return ERROR_FAIL;
1879                 }
1880
1881                 int ret = add_service(&semihosting_service_driver,
1882                                 port, 1, service);
1883
1884                 if (ret != ERROR_OK) {
1885                         LOG_ERROR("failed to initialize %s", service->name);
1886                         free(service->name);
1887                         free(service);
1888                         return ERROR_FAIL;
1889                 }
1890         }
1891
1892         semihosting->redirect_cfg = cfg;
1893
1894         return ERROR_OK;
1895 }
1896
1897 COMMAND_HANDLER(handle_common_semihosting_fileio_command)
1898 {
1899         struct target *target = get_current_target(CMD_CTX);
1900
1901         if (!target) {
1902                 LOG_ERROR("No target selected");
1903                 return ERROR_FAIL;
1904         }
1905
1906         struct semihosting *semihosting = target->semihosting;
1907         if (!semihosting) {
1908                 command_print(CMD, "semihosting not supported for current target");
1909                 return ERROR_FAIL;
1910         }
1911
1912         if (!semihosting->is_active) {
1913                 command_print(CMD, "semihosting not yet enabled for current target");
1914                 return ERROR_FAIL;
1915         }
1916
1917         if (CMD_ARGC > 0)
1918                 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);
1919
1920         command_print(CMD, "semihosting fileio is %s",
1921                 semihosting->is_fileio
1922                 ? "enabled" : "disabled");
1923
1924         return ERROR_OK;
1925 }
1926
1927 COMMAND_HANDLER(handle_common_semihosting_cmdline)
1928 {
1929         struct target *target = get_current_target(CMD_CTX);
1930         unsigned int i;
1931
1932         if (!target) {
1933                 LOG_ERROR("No target selected");
1934                 return ERROR_FAIL;
1935         }
1936
1937         struct semihosting *semihosting = target->semihosting;
1938         if (!semihosting) {
1939                 command_print(CMD, "semihosting not supported for current target");
1940                 return ERROR_FAIL;
1941         }
1942
1943         free(semihosting->cmdline);
1944         semihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1945
1946         for (i = 1; i < CMD_ARGC; i++) {
1947                 char *cmdline = alloc_printf("%s %s", semihosting->cmdline, CMD_ARGV[i]);
1948                 if (!cmdline)
1949                         break;
1950                 free(semihosting->cmdline);
1951                 semihosting->cmdline = cmdline;
1952         }
1953
1954         command_print(CMD, "semihosting command line is [%s]",
1955                 semihosting->cmdline);
1956
1957         return ERROR_OK;
1958 }
1959
1960 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
1961 {
1962         struct target *target = get_current_target(CMD_CTX);
1963
1964         if (!target) {
1965                 LOG_ERROR("No target selected");
1966                 return ERROR_FAIL;
1967         }
1968
1969         struct semihosting *semihosting = target->semihosting;
1970         if (!semihosting) {
1971                 command_print(CMD, "semihosting not supported for current target");
1972                 return ERROR_FAIL;
1973         }
1974
1975         if (!semihosting->is_active) {
1976                 command_print(CMD, "semihosting not yet enabled for current target");
1977                 return ERROR_FAIL;
1978         }
1979
1980         if (CMD_ARGC > 0)
1981                 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);
1982
1983         command_print(CMD, "semihosting resumable exit is %s",
1984                 semihosting->has_resumable_exit
1985                 ? "enabled" : "disabled");
1986
1987         return ERROR_OK;
1988 }
1989
1990 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
1991 {
1992         struct target *target = get_current_target(CMD_CTX);
1993         struct semihosting *semihosting = target->semihosting;
1994
1995         if (CMD_ARGC)
1996                 return ERROR_COMMAND_SYNTAX_ERROR;
1997
1998         if (!semihosting->is_active) {
1999                 LOG_ERROR("semihosting not yet enabled for current target");
2000                 return ERROR_FAIL;
2001         }
2002
2003         if (!semihosting_user_op_params) {
2004                 LOG_ERROR("This command is usable only from a registered user "
2005                                 "semihosting event callback.");
2006                 return ERROR_FAIL;
2007         }
2008
2009         command_print_sameline(CMD, "%s", semihosting_user_op_params);
2010
2011         return ERROR_OK;
2012 }
2013
2014 COMMAND_HANDLER(handle_common_semihosting_basedir_command)
2015 {
2016         struct target *target = get_current_target(CMD_CTX);
2017
2018         if (CMD_ARGC > 1)
2019                 return ERROR_COMMAND_SYNTAX_ERROR;
2020
2021         if (!target) {
2022                 LOG_ERROR("No target selected");
2023                 return ERROR_FAIL;
2024         }
2025
2026         struct semihosting *semihosting = target->semihosting;
2027         if (!semihosting) {
2028                 command_print(CMD, "semihosting not supported for current target");
2029                 return ERROR_FAIL;
2030         }
2031
2032         if (!semihosting->is_active) {
2033                 command_print(CMD, "semihosting not yet enabled for current target");
2034                 return ERROR_FAIL;
2035         }
2036
2037         if (CMD_ARGC > 0) {
2038                 free(semihosting->basedir);
2039                 semihosting->basedir = strdup(CMD_ARGV[0]);
2040                 if (!semihosting->basedir) {
2041                         command_print(CMD, "semihosting failed to allocate memory for basedir!");
2042                         return ERROR_FAIL;
2043                 }
2044         }
2045
2046         command_print(CMD, "semihosting base dir: %s",
2047                 semihosting->basedir ? semihosting->basedir : "");
2048
2049         return ERROR_OK;
2050 }
2051
2052 const struct command_registration semihosting_common_handlers[] = {
2053         {
2054                 .name = "semihosting",
2055                 .handler = handle_common_semihosting_command,
2056                 .mode = COMMAND_EXEC,
2057                 .usage = "['enable'|'disable']",
2058                 .help = "activate support for semihosting operations",
2059         },
2060         {
2061                 .name = "semihosting_redirect",
2062                 .handler = handle_common_semihosting_redirect_command,
2063                 .mode = COMMAND_EXEC,
2064                 .usage = "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2065                 .help = "redirect semihosting IO",
2066         },
2067         {
2068                 .name = "semihosting_cmdline",
2069                 .handler = handle_common_semihosting_cmdline,
2070                 .mode = COMMAND_EXEC,
2071                 .usage = "arguments",
2072                 .help = "command line arguments to be passed to program",
2073         },
2074         {
2075                 .name = "semihosting_fileio",
2076                 .handler = handle_common_semihosting_fileio_command,
2077                 .mode = COMMAND_EXEC,
2078                 .usage = "['enable'|'disable']",
2079                 .help = "activate support for semihosting fileio operations",
2080         },
2081         {
2082                 .name = "semihosting_resexit",
2083                 .handler = handle_common_semihosting_resumable_exit_command,
2084                 .mode = COMMAND_EXEC,
2085                 .usage = "['enable'|'disable']",
2086                 .help = "activate support for semihosting resumable exit",
2087         },
2088         {
2089                 .name = "semihosting_read_user_param",
2090                 .handler = handle_common_semihosting_read_user_param_command,
2091                 .mode = COMMAND_EXEC,
2092                 .usage = "",
2093                 .help = "read parameters in semihosting-user-cmd-0x10X callbacks",
2094         },
2095         {
2096                 .name = "semihosting_basedir",
2097                 .handler = handle_common_semihosting_basedir_command,
2098                 .mode = COMMAND_EXEC,
2099                 .usage = "[dir]",
2100                 .help = "set the base directory for semihosting I/O operations",
2101         },
2102         COMMAND_REGISTRATION_DONE
2103 };