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