81 O_WRONLY | O_CREAT | O_TRUNC,
82 O_WRONLY | O_CREAT | O_TRUNC |
O_BINARY,
83 O_RDWR | O_CREAT | O_TRUNC,
84 O_RDWR | O_CREAT | O_TRUNC |
O_BINARY,
85 O_WRONLY | O_CREAT | O_APPEND,
86 O_WRONLY | O_CREAT | O_APPEND |
O_BINARY,
87 O_RDWR | O_CREAT | O_APPEND,
88 O_RDWR | O_CREAT | O_APPEND |
O_BINARY
94 int fileio_errno,
bool ctrl_c);
169 bool is_read_op =
false;
207 LOG_ERROR(
"No connected TCP client for semihosting");
228 int result = write(fd, buf,
size);
237 LOG_ERROR(
"No connected TCP client for semihosting");
275 ssize_t result = read(fd, buf,
size);
322 return "EXIT_EXTENDED";
326 return "GET_CMDLINE";
362 return "ARM_RESERVED_CMD";
458 if (fd == 0 || fd == 1 || fd == 2) {
459 LOG_DEBUG(
"ignoring semihosting attempt to close %s",
460 (fd == 0) ?
"stdin" :
461 (fd == 1) ?
"stdout" :
"stderr");
566 "semihosting: *** application exited with %d ***\n",
571 "semihosting: application exception %#x\n",
581 "semihosting: *** application exited normally ***\n");
590 "semihosting: *** application exited with error ***\n");
597 "semihosting: application exception %#x\n",
657 "semihosting: *** application exited with %d ***\n",
661 fprintf(stderr,
"semihosting: exception %#x\n",
745 uint32_t len = strlen(arg) + 1;
922 uint8_t *fn = malloc(basedir_len + len + 2);
927 if (basedir_len > 0) {
929 if (fn[basedir_len - 1] !=
'/')
930 fn[basedir_len++] =
'/';
937 fn[basedir_len + len] = 0;
941 if (strcmp((
char *)fn,
":semihosting-features") == 0) {
944 }
else if (strcmp((
char *)fn,
":tt") == 0) {
947 }
else if (
mode == 4) {
949 }
else if (
mode == 8) {
964 if (strcmp((
char *)fn,
":tt") == 0) {
971 fd = dup(STDIN_FILENO);
974 }
else if (
mode < 8) {
975 fd = dup(STDOUT_FILENO);
979 fd = dup(STDERR_FILENO);
1052 uint8_t *buf = malloc(len);
1058 LOG_DEBUG(
"read(%d, 0x%" PRIx64
", %zu)=%" PRId64,
1094 LOG_ERROR(
"SYS_READC not supported by semihosting fileio");
1129 uint8_t *fn = malloc(len+1);
1187 uint8_t *fn1 = malloc(len1+1);
1188 uint8_t *fn2 = malloc(len2+1);
1257 fileio_info->
param_3 = SEEK_SET;
1304 uint8_t *
cmd = malloc(len+1);
1388 uint8_t *buf = malloc(len);
1399 LOG_DEBUG(
"write(%d, 0x%" PRIx64
", %zu)=%" PRId64,
1521 LOG_ERROR(
"Failed to read fields for user defined command"
1530 LOG_ERROR(
"The maximum length for user defined command "
1531 "parameter is %u, received length is %zu (op=0x%x)",
1546 LOG_ERROR(
"Failed to read from target, semihosting op=0x%x (%s)",
1636 fprintf(stderr,
"semihosting: unsupported call %#x\n",
1645 LOG_ERROR(
"Failed to post semihosting result");
1675 int fileio_errno,
bool ctrl_c)
1707 bool fileio_failed =
false;
1789 const int buf_len = 100;
1793 if (bytes_read == 0) {
1795 }
else if (bytes_read == -1) {
1796 LOG_ERROR(
"error during read: %s", strerror(errno));
1827 .
name =
"semihosting",
1828 .new_connection_during_keep_alive_handler =
NULL,
1832 .keep_client_alive_handler =
NULL,
1864 LOG_ERROR(
"Failed to Configure semihosting");
1874 ?
"enabled" :
"disabled");
1905 if (strcmp(
CMD_ARGV[0],
"disable") == 0) {
1909 }
else if (strcmp(
CMD_ARGV[0],
"tcp") == 0) {
1910 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1917 if (strcmp(
CMD_ARGV[2],
"debug") == 0)
1919 else if (strcmp(
CMD_ARGV[2],
"stdio") == 0)
1921 else if (strcmp(
CMD_ARGV[2],
"all") != 0)
1935 LOG_ERROR(
"Failed to allocate semihosting TCP service.");
1989 ?
"enabled" :
"disabled");
2052 ?
"enabled" :
"disabled");
2066 LOG_ERROR(
"semihosting not yet enabled for current target");
2071 LOG_ERROR(
"This command is usable only from a registered user "
2072 "semihosting event callback.");
2121 .
name =
"semihosting",
2122 .handler = handle_common_semihosting_command,
2124 .usage =
"['enable'|'disable']",
2125 .help =
"activate support for semihosting operations",
2128 .name =
"semihosting_redirect",
2129 .handler = handle_common_semihosting_redirect_command,
2131 .usage =
"(disable | tcp <port> ['debug'|'stdio'|'all'])",
2132 .help =
"redirect semihosting IO",
2135 .name =
"semihosting_cmdline",
2136 .handler = handle_common_semihosting_cmdline,
2138 .usage =
"arguments",
2139 .help =
"command line arguments to be passed to program",
2142 .name =
"semihosting_fileio",
2143 .handler = handle_common_semihosting_fileio_command,
2145 .usage =
"['enable'|'disable']",
2146 .help =
"activate support for semihosting fileio operations",
2149 .name =
"semihosting_resexit",
2150 .handler = handle_common_semihosting_resumable_exit_command,
2152 .usage =
"['enable'|'disable']",
2153 .help =
"activate support for semihosting resumable exit",
2156 .name =
"semihosting_read_user_param",
2157 .handler = handle_common_semihosting_read_user_param_command,
2160 .help =
"read parameters in semihosting-user-cmd-0x10X callbacks",
2163 .name =
"semihosting_basedir",
2164 .handler = handle_common_semihosting_basedir_command,
2167 .help =
"set the base directory for semihosting I/O operations",
static int post_result(struct target *target)
Support functions to access arbitrary bits in a byte array.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_ENABLE(in, out)
parses an enable/disable command argument
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
enum esirisc_reg_num number
int gdb_get_actual_connections(void)
void log_socket_error(const char *socket_desc)
char * alloc_printf(const char *format,...)
#define ERROR_NOT_IMPLEMENTED
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
target_addr_t addr
Start address to search for the control block.
size_t size
Size of the control block search area.
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 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 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)
static const char * semihosting_opcode_to_str(const uint64_t opcode)
Convert the syscall opcode to a human-readable string.
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.
int semihosting_common(struct target *target)
Portable implementation of ARM semihosting calls.
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 int semihosting_write_fields(struct target *target, size_t number, uint8_t *fields)
Write all fields of a command from buffer to target.
static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
static int semihosting_common_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
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_ISERROR
@ SEMIHOSTING_USER_CMD_0X1FF
@ SEMIHOSTING_SYS_GET_CMDLINE
@ SEMIHOSTING_SYS_EXIT_EXTENDED
@ SEMIHOSTING_ARM_RESERVED_END
@ SEMIHOSTING_ARM_RESERVED_START
@ SEMIHOSTING_SYS_HEAPINFO
@ SEMIHOSTING_SYS_ELAPSED
@ SEMIHOSTING_USER_CMD_0X100
int connection_write(struct connection *connection, const void *data, int len)
int connection_read(struct connection *connection, void *data, int len)
int remove_service(const char *name, const char *port)
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
#define ERROR_SERVER_REMOTE_CLOSED
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
int(* gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c)
int(* get_gdb_fileio_info)(struct target *target, struct gdb_fileio_info *fileio_info)
struct semihosting * semihosting
struct gdb_fileio_info * fileio_info
struct target_type * type
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
int target_call_event_callbacks(struct target *target, enum target_event event)
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
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.
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value)
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.
struct target * get_current_target(struct command_context *cmd_ctx)
void target_handle_event(struct target *target, enum target_event e)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
static bool target_was_examined(const struct target *target)
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.