Add new "arg" sub-argument to the --semihosting-config allowing to pass multiple input argument separately. It is required for example by UHI semihosting to construct argc and argv.
Signed-off-by: Leon Alrae <leon.al...@imgtec.com> --- include/exec/semihost.h | 12 ++++++++++++ qemu-options.hx | 8 +++++--- vl.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/include/exec/semihost.h b/include/exec/semihost.h index c2f0bcb..6e4e8c0 100644 --- a/include/exec/semihost.h +++ b/include/exec/semihost.h @@ -36,9 +36,21 @@ static inline SemihostingTarget semihosting_get_target(void) { return SEMIHOSTING_TARGET_AUTO; } + +static inline const char *semihosting_get_arg(int i) +{ + return NULL; +} + +static inline int semihosting_get_argc(void) +{ + return 0; +} #else bool semihosting_enabled(void); SemihostingTarget semihosting_get_target(void); +const char *semihosting_get_arg(int i); +int semihosting_get_argc(void); #endif #endif diff --git a/qemu-options.hx b/qemu-options.hx index ec356f6..ed2a7e8 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3296,14 +3296,16 @@ STEXI Enable semihosting mode (ARM, M68K, Xtensa only). ETEXI DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config, - "-semihosting-config [enable=on|off,]target=native|gdb|auto semihosting configuration\n", + "-semihosting-config [enable=on|off][,target=native|gdb|auto][,arg=str[,...]]\n" \ + " semihosting configuration\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32) STEXI -@item -semihosting-config [enable=on|off,]target=native|gdb|auto +@item -semihosting-config [enable=on|off][,target=native|gdb|auto][,arg=str[,...]] @findex -semihosting-config Enable semihosting and define where the semihosting calls will be addressed, to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, which means -@code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, Xtensa only). +@code{gdb} during debug sessions and @code{native} otherwise. The @var{arg} allows to +pass input arguments, can be used multiple times to build up a list (ARM, M68K, Xtensa only) ETEXI DEF("old-param", 0, QEMU_OPTION_old_param, "-old-param old param mode\n", QEMU_ARCH_ARM) diff --git a/vl.c b/vl.c index f3319a9..c8ac1e6 100644 --- a/vl.c +++ b/vl.c @@ -486,6 +486,9 @@ static QemuOptsList qemu_semihosting_config_opts = { }, { .name = "target", .type = QEMU_OPT_STRING, + }, { + .name = "arg", + .type = QEMU_OPT_STRING, }, { /* end of list */ } }, @@ -1230,6 +1233,8 @@ static void configure_msg(QemuOpts *opts) typedef struct SemihostingConfig { bool enabled; SemihostingTarget target; + const char **argv; + int argc; } SemihostingConfig; static SemihostingConfig semihosting; @@ -1244,6 +1249,31 @@ SemihostingTarget semihosting_get_target(void) return semihosting.target; } +const char *semihosting_get_arg(int i) +{ + if (i >= semihosting.argc) { + return NULL; + } + + return semihosting.argv[i]; +} + +int semihosting_get_argc(void) +{ + return semihosting.argc; +} + +static int add_semihosting_arg(const char *name, const char *val, void *opaque) +{ + SemihostingConfig *s = opaque; + if (strcmp(name, "arg") == 0) { + s->argc++; + s->argv = g_realloc(s->argv, s->argc * sizeof(void *)); + s->argv[s->argc - 1] = val; + } + return 0; +} + /***********************************************************/ /* USB devices */ @@ -3592,6 +3622,9 @@ int main(int argc, char **argv, char **envp) } else { semihosting.target = SEMIHOSTING_TARGET_AUTO; } + /* Set semihosting argument count and vector */ + qemu_opt_foreach(opts, add_semihosting_arg, + &semihosting, 0); } else { fprintf(stderr, "Unsupported semihosting-config %s\n", optarg);