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