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