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