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