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 | 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 | 82 | uint32_t do_arm_semihosting(CPUState *env) |
82 | 83 | { |
83 | 84 | target_ulong args; |
... | ... | @@ -158,10 +159,41 @@ uint32_t do_arm_semihosting(CPUState *env) |
158 | 159 | case SYS_ERRNO: |
159 | 160 | return ts->swi_errno; |
160 | 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 | 197 | case SYS_HEAPINFO: |
166 | 198 | { |
167 | 199 | uint32_t *ptr; | ... | ... |
linux-user/linuxload.c