diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-11-19 20:29:35 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-11-19 20:29:35 +0000 |
commit | 38d0662a4cf196cc059c9e27f634b13fb24fce2d (patch) | |
tree | bd4c37654250a2fe94a30d42f8bdc4b29b9cd474 | |
parent | 1be9e1dc569eb3817441baf60d26648c5dcef12d (diff) |
Arm semihosted commandline support (Wolfgang Schildbach).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2216 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | linux-user/arm-semi.c | 42 | ||||
-rw-r--r-- | linux-user/linuxload.c | 2 | ||||
-rw-r--r-- | linux-user/qemu.h | 1 |
3 files changed, 40 insertions, 5 deletions
diff --git a/linux-user/arm-semi.c b/linux-user/arm-semi.c index 250d5b75cc..b182eb4080 100644 --- a/linux-user/arm-semi.c +++ b/linux-user/arm-semi.c @@ -77,7 +77,8 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) return code; } -#define ARG(n) tget32(args + n * 4) +#define ARG(n) tget32(args + (n) * 4) +#define SET_ARG(n, val) tput32(args + (n) * 4,val) uint32_t do_arm_semihosting(CPUState *env) { target_ulong args; @@ -158,10 +159,41 @@ uint32_t do_arm_semihosting(CPUState *env) case SYS_ERRNO: return ts->swi_errno; case SYS_GET_CMDLINE: - /* XXX: Not implemented. */ - s = (char *)g2h(ARG(0)); - *s = 0; - return -1; + /* Build a commandline from the original argv. */ + { + char **arg = ts->info->host_argv; + int len = ARG(1); + /* lock the buffer on the ARM side */ + char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0); + + s = cmdline_buffer; + while (*arg && len > 2) { + int n = strlen(*arg); + + if (s != cmdline_buffer) { + *(s++) = ' '; + len--; + } + if (n >= len) + n = len - 1; + memcpy(s, *arg, n); + s += n; + len -= n; + arg++; + } + /* Null terminate the string. */ + *s = 0; + len = s - cmdline_buffer; + + /* Unlock the buffer on the ARM side. */ + unlock_user(cmdline_buffer, ARG(0), len); + + /* Adjust the commandline length argument. */ + SET_ARG(1, len); + + /* Return success if commandline fit into buffer. */ + return *arg ? -1 : 0; + } case SYS_HEAPINFO: { uint32_t *ptr; diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ef5409b95f..2d20c000db 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -162,6 +162,8 @@ int loader_exec(const char * filename, char ** argv, char ** envp, retval = prepare_binprm(&bprm); + infop->host_argv = argv; + if(retval>=0) { if (bprm.buf[0] == 0x7f && bprm.buf[1] == 'E' diff --git a/linux-user/qemu.h b/linux-user/qemu.h index d35455de33..f894dde084 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -29,6 +29,7 @@ struct image_info { unsigned long entry; target_ulong code_offset; target_ulong data_offset; + char **host_argv; int personality; }; |