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