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