This is an automated email from Gerrit.

"Erhan Kurubas <erhankuru...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6888

-- gerrit

commit f43c975ee1c4c874b95521b6347315e3bdd42620
Author: erhankur <erhankuru...@gmail.com>
Date:   Tue Apr 5 13:49:28 2022 +0300

    semihosting: add semihosting_basedir command
    
    This command allows users to set base working directory for the semihosting 
I/O operations.
    Default is the current OpenOCD directory.
    
    Signed-off-by: erhankur <erhankuru...@gmail.com>
    Change-Id: I80c5979e4c96d66cccdd12cc6fcd5f353e5c6b4d

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 1b6d063028..50e7d46d06 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -9441,6 +9441,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 I/O directory relative to the OpenOCD working directory.
+Use "." for the current directory.
+@end deffn
+
 @section ARMv4 and ARMv5 Architecture
 @cindex ARMv4
 @cindex ARMv5
diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index bc1f417ef0..ef05dbe577 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -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,19 @@ 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 + 1);
                                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);
+                                       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 +2028,41 @@ 
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 (!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 +2106,12 @@ const struct command_registration 
semihosting_common_handlers[] = {
                .usage = "",
                .help = "read parameters in semihosting-user-cmd-0x10X 
callbacks",
        },
+       {
+               "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
 };
diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h
index 459faf656a..f897e284d5 100644
--- a/src/target/semihosting_common.h
+++ b/src/target/semihosting_common.h
@@ -176,6 +176,8 @@ 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);
 };

-- 

Reply via email to