]> git.gag.com Git - fw/openocd/commitdiff
semihosting: add semihosting_basedir command
authorErhan Kurubas <erhan.kurubas@espressif.com>
Tue, 5 Apr 2022 10:49:28 +0000 (13:49 +0300)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 21 May 2022 09:01:56 +0000 (09:01 +0000)
This command allows users to set base working directory for the
semihosting I/O operations.Default is the current OpenOCD directory.

Signed-off-by: Erhan Kurubas <erhan.kurubas@espressif.com>
Change-Id: I80c5979e4c96d66cccdd12cc6fcd5f353e5c6b4d
Reviewed-on: https://review.openocd.org/c/openocd/+/6888
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
doc/openocd.texi
src/target/semihosting_common.c
src/target/semihosting_common.h
src/target/target.c

index be9e5ac085f8e832348334b509f76ab741348b8f..cc1d10441150dbb6ff6ce2e5aa4ae75d49d5aeda 100644 (file)
@@ -9624,6 +9624,12 @@ is valid during the run of the event handlers and is accessible with this
 command.
 @end deffn
 
+@deffn {Command} {arm semihosting_basedir} [dir]
+@cindex ARM semihosting
+Set the base directory for semihosting I/O, either an absolute path or a path relative to OpenOCD working directory.
+Use "." for the current directory.
+@end deffn
+
 @section ARMv4 and ARMv5 Architecture
 @cindex ARMv4
 @cindex ARMv5
index bc1f417ef0535ba43f2e795869382eb3f205479c..2df6e38aeaadbfd10dceb847770b06ff82a17004 100644 (file)
@@ -159,6 +159,7 @@ int semihosting_common_init(struct target *target, void *setup,
        semihosting->result = -1;
        semihosting->sys_errno = -1;
        semihosting->cmdline = NULL;
+       semihosting->basedir = NULL;
 
        /* If possible, update it in setup(). */
        semihosting->setup_time = clock();
@@ -870,17 +871,21 @@ int semihosting_common(struct target *target)
                                        semihosting->sys_errno = EINVAL;
                                        break;
                                }
-                               uint8_t *fn = malloc(len+1);
+                               size_t basedir_len = semihosting->basedir ? strlen(semihosting->basedir) : 0;
+                               uint8_t *fn = malloc(basedir_len + len + 2);
                                if (!fn) {
                                        semihosting->result = -1;
                                        semihosting->sys_errno = ENOMEM;
                                } else {
-                                       retval = target_read_memory(target, addr, 1, len, fn);
+                                       strncpy((char *)fn, semihosting->basedir, basedir_len);
+                                       if (fn[basedir_len - 1] != '/')
+                                               fn[basedir_len++] = '/';
+                                       retval = target_read_memory(target, addr, 1, len, fn + basedir_len);
                                        if (retval != ERROR_OK) {
                                                free(fn);
                                                return retval;
                                        }
-                                       fn[len] = 0;
+                                       fn[basedir_len + len] = 0;
                                        /* TODO: implement the :semihosting-features special file.
                                         * */
                                        if (semihosting->is_fileio) {
@@ -2025,6 +2030,44 @@ COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_common_semihosting_basedir_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+
+       if (CMD_ARGC > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (!target) {
+               LOG_ERROR("No target selected");
+               return ERROR_FAIL;
+       }
+
+       struct semihosting *semihosting = target->semihosting;
+       if (!semihosting) {
+               command_print(CMD, "semihosting not supported for current target");
+               return ERROR_FAIL;
+       }
+
+       if (!semihosting->is_active) {
+               command_print(CMD, "semihosting not yet enabled for current target");
+               return ERROR_FAIL;
+       }
+
+       if (CMD_ARGC > 0) {
+               free(semihosting->basedir);
+               semihosting->basedir = strdup(CMD_ARGV[0]);
+               if (!semihosting->basedir) {
+                       command_print(CMD, "semihosting failed to allocate memory for basedir!");
+                       return ERROR_FAIL;
+               }
+       }
+
+       command_print(CMD, "semihosting base dir: %s",
+               semihosting->basedir ? semihosting->basedir : "");
+
+       return ERROR_OK;
+}
+
 const struct command_registration semihosting_common_handlers[] = {
        {
                .name = "semihosting",
@@ -2068,5 +2111,12 @@ const struct command_registration semihosting_common_handlers[] = {
                .usage = "",
                .help = "read parameters in semihosting-user-cmd-0x10X callbacks",
        },
+       {
+               .name = "semihosting_basedir",
+               .handler = handle_common_semihosting_basedir_command,
+               .mode = COMMAND_EXEC,
+               .usage = "[dir]",
+               .help = "set the base directory for semihosting I/O operations",
+       },
        COMMAND_REGISTRATION_DONE
 };
index 459faf656abf6a07afb666aa8763ea8a0c30ef83..404080f023401b81f0871c58900afc286c5e17f5 100644 (file)
@@ -176,6 +176,9 @@ struct semihosting {
        /** The current time when 'execution starts' */
        clock_t setup_time;
 
+       /** Base directory for semihosting I/O operations. */
+       char *basedir;
+
        int (*setup)(struct target *target, int enable);
        int (*post_result)(struct target *target);
 };
index 8a451883ba4ccdedca12408cd655ca2c51e61b6a..8edd632916a7877cacf4c5f25045f97b570221fe 100644 (file)
@@ -57,6 +57,7 @@
 #include "transport/transport.h"
 #include "arm_cti.h"
 #include "smp.h"
+#include "semihosting_common.h"
 
 /* default halt wait timeout (ms) */
 #define DEFAULT_HALT_TIMEOUT 5000
@@ -2258,6 +2259,8 @@ static void target_destroy(struct target *target)
        if (target->type->deinit_target)
                target->type->deinit_target(target);
 
+       if (target->semihosting)
+               free(target->semihosting->basedir);
        free(target->semihosting);
 
        jtag_unregister_event_callback(jtag_enable_callback, target);