Commit 38d0662a4cf196cc059c9e27f634b13fb24fce2d
1 parent
1be9e1dc
Arm semihosted commandline support (Wolfgang Schildbach).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2216 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
40 additions
and
5 deletions
linux-user/arm-semi.c
@@ -77,7 +77,8 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) | @@ -77,7 +77,8 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) | ||
77 | return code; | 77 | return code; |
78 | } | 78 | } |
79 | 79 | ||
80 | -#define ARG(n) tget32(args + n * 4) | 80 | +#define ARG(n) tget32(args + (n) * 4) |
81 | +#define SET_ARG(n, val) tput32(args + (n) * 4,val) | ||
81 | uint32_t do_arm_semihosting(CPUState *env) | 82 | uint32_t do_arm_semihosting(CPUState *env) |
82 | { | 83 | { |
83 | target_ulong args; | 84 | target_ulong args; |
@@ -158,10 +159,41 @@ uint32_t do_arm_semihosting(CPUState *env) | @@ -158,10 +159,41 @@ uint32_t do_arm_semihosting(CPUState *env) | ||
158 | case SYS_ERRNO: | 159 | case SYS_ERRNO: |
159 | return ts->swi_errno; | 160 | return ts->swi_errno; |
160 | case SYS_GET_CMDLINE: | 161 | case SYS_GET_CMDLINE: |
161 | - /* XXX: Not implemented. */ | ||
162 | - s = (char *)g2h(ARG(0)); | ||
163 | - *s = 0; | ||
164 | - return -1; | 162 | + /* Build a commandline from the original argv. */ |
163 | + { | ||
164 | + char **arg = ts->info->host_argv; | ||
165 | + int len = ARG(1); | ||
166 | + /* lock the buffer on the ARM side */ | ||
167 | + char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0); | ||
168 | + | ||
169 | + s = cmdline_buffer; | ||
170 | + while (*arg && len > 2) { | ||
171 | + int n = strlen(*arg); | ||
172 | + | ||
173 | + if (s != cmdline_buffer) { | ||
174 | + *(s++) = ' '; | ||
175 | + len--; | ||
176 | + } | ||
177 | + if (n >= len) | ||
178 | + n = len - 1; | ||
179 | + memcpy(s, *arg, n); | ||
180 | + s += n; | ||
181 | + len -= n; | ||
182 | + arg++; | ||
183 | + } | ||
184 | + /* Null terminate the string. */ | ||
185 | + *s = 0; | ||
186 | + len = s - cmdline_buffer; | ||
187 | + | ||
188 | + /* Unlock the buffer on the ARM side. */ | ||
189 | + unlock_user(cmdline_buffer, ARG(0), len); | ||
190 | + | ||
191 | + /* Adjust the commandline length argument. */ | ||
192 | + SET_ARG(1, len); | ||
193 | + | ||
194 | + /* Return success if commandline fit into buffer. */ | ||
195 | + return *arg ? -1 : 0; | ||
196 | + } | ||
165 | case SYS_HEAPINFO: | 197 | case SYS_HEAPINFO: |
166 | { | 198 | { |
167 | uint32_t *ptr; | 199 | uint32_t *ptr; |
linux-user/linuxload.c
@@ -162,6 +162,8 @@ int loader_exec(const char * filename, char ** argv, char ** envp, | @@ -162,6 +162,8 @@ int loader_exec(const char * filename, char ** argv, char ** envp, | ||
162 | 162 | ||
163 | retval = prepare_binprm(&bprm); | 163 | retval = prepare_binprm(&bprm); |
164 | 164 | ||
165 | + infop->host_argv = argv; | ||
166 | + | ||
165 | if(retval>=0) { | 167 | if(retval>=0) { |
166 | if (bprm.buf[0] == 0x7f | 168 | if (bprm.buf[0] == 0x7f |
167 | && bprm.buf[1] == 'E' | 169 | && bprm.buf[1] == 'E' |
linux-user/qemu.h
@@ -29,6 +29,7 @@ struct image_info { | @@ -29,6 +29,7 @@ struct image_info { | ||
29 | unsigned long entry; | 29 | unsigned long entry; |
30 | target_ulong code_offset; | 30 | target_ulong code_offset; |
31 | target_ulong data_offset; | 31 | target_ulong data_offset; |
32 | + char **host_argv; | ||
32 | int personality; | 33 | int personality; |
33 | }; | 34 | }; |
34 | 35 |