Commit 38d0662a4cf196cc059c9e27f634b13fb24fce2d

Authored by pbrook
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
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
... ... @@ -162,6 +162,8 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
162 162  
163 163 retval = prepare_binprm(&bprm);
164 164  
  165 + infop->host_argv = argv;
  166 +
165 167 if(retval>=0) {
166 168 if (bprm.buf[0] == 0x7f
167 169 && bprm.buf[1] == 'E'
... ...
linux-user/qemu.h
... ... @@ -29,6 +29,7 @@ struct image_info {
29 29 unsigned long entry;
30 30 target_ulong code_offset;
31 31 target_ulong data_offset;
  32 + char **host_argv;
32 33 int personality;
33 34 };
34 35  
... ...