Arm semihosted commandline support (Wolfgang Schildbach).

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2216 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2006-11-19 20:29:35 +00:00
parent 1be9e1dc56
commit 38d0662a4c
3 changed files with 40 additions and 5 deletions

View File

@ -77,7 +77,8 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
return 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) uint32_t do_arm_semihosting(CPUState *env)
{ {
target_ulong args; target_ulong args;
@ -158,10 +159,41 @@ uint32_t do_arm_semihosting(CPUState *env)
case SYS_ERRNO: case SYS_ERRNO:
return ts->swi_errno; return ts->swi_errno;
case SYS_GET_CMDLINE: case SYS_GET_CMDLINE:
/* XXX: Not implemented. */ /* Build a commandline from the original argv. */
s = (char *)g2h(ARG(0)); {
*s = 0; char **arg = ts->info->host_argv;
return -1; 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: case SYS_HEAPINFO:
{ {
uint32_t *ptr; uint32_t *ptr;

View File

@ -162,6 +162,8 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
retval = prepare_binprm(&bprm); retval = prepare_binprm(&bprm);
infop->host_argv = argv;
if(retval>=0) { if(retval>=0) {
if (bprm.buf[0] == 0x7f if (bprm.buf[0] == 0x7f
&& bprm.buf[1] == 'E' && bprm.buf[1] == 'E'

View File

@ -29,6 +29,7 @@ struct image_info {
unsigned long entry; unsigned long entry;
target_ulong code_offset; target_ulong code_offset;
target_ulong data_offset; target_ulong data_offset;
char **host_argv;
int personality; int personality;
}; };