automatic ioctl number conversion - minimum ARM fork() support

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@240 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-06-15 19:56:46 +00:00
parent 2437490100
commit 2ab83ea784
1 changed files with 54 additions and 18 deletions

View File

@ -68,11 +68,6 @@
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
long do_sigreturn(CPUX86State *env);
long do_rt_sigreturn(CPUX86State *env);
#define __NR_sys_uname __NR_uname
#define __NR_sys_getcwd1 __NR_getcwd
#define __NR_sys_statfs __NR_statfs
@ -702,8 +697,8 @@ enum {
#undef STRUCT_SPECIAL
typedef struct IOCTLEntry {
int target_cmd;
int host_cmd;
unsigned int target_cmd;
unsigned int host_cmd;
const char *name;
int access;
const argtype arg_type[5];
@ -715,7 +710,7 @@ typedef struct IOCTLEntry {
#define MAX_STRUCT_SIZE 4096
const IOCTLEntry ioctl_entries[] = {
IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, types...) \
{ TARGET_ ## cmd, cmd, #cmd, access, { types } },
#include "ioctls.h"
@ -970,7 +965,7 @@ static bitmask_transtbl mmap_flags_tbl[] = {
{ 0, 0, 0, 0 }
};
#ifdef TARGET_I386
#if defined(TARGET_I386)
/* NOTE: there is really one LDT for all the threads */
uint8_t *ldt_table;
@ -1087,28 +1082,28 @@ int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount
return ret;
}
#endif /* defined(TARGET_I386) */
/* this stack is the equivalent of the kernel stack associated with a
thread/process */
#define NEW_STACK_SIZE 8192
static int clone_func(void *arg)
{
CPUX86State *env = arg;
CPUState *env = arg;
cpu_loop(env);
/* never exits */
return 0;
}
int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
{
int ret;
TaskState *ts;
uint8_t *new_stack;
CPUX86State *new_env;
CPUState *new_env;
if (flags & CLONE_VM) {
if (!newsp)
newsp = env->regs[R_ESP];
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
memset(ts, 0, sizeof(TaskState));
new_stack = ts->stack;
@ -1117,10 +1112,21 @@ int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
ts->next = first_task_state;
first_task_state = ts;
/* we create a new CPU instance. */
new_env = cpu_x86_init();
memcpy(new_env, env, sizeof(CPUX86State));
new_env = cpu_init();
memcpy(new_env, env, sizeof(CPUState));
#if defined(TARGET_I386)
if (!newsp)
newsp = env->regs[R_ESP];
new_env->regs[R_ESP] = newsp;
new_env->regs[R_EAX] = 0;
#elif defined(TARGET_ARM)
if (!newsp)
newsp = env->regs[13];
new_env->regs[13] = newsp;
new_env->regs[0] = 0;
#else
#error unsupported target CPU
#endif
new_env->opaque = ts;
#ifdef __ia64__
ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
@ -1136,8 +1142,6 @@ int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
return ret;
}
#endif
static long do_fcntl(int fd, int cmd, unsigned long arg)
{
struct flock fl;
@ -1188,11 +1192,43 @@ static long do_fcntl(int fd, int cmd, unsigned long arg)
void syscall_init(void)
{
IOCTLEntry *ie;
const argtype *arg_type;
int size;
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
#include "syscall_types.h"
#undef STRUCT
#undef STRUCT_SPECIAL
/* we patch the ioctl size if necessary. We rely on the fact that
no ioctl has all the bits at '1' in the size field */
ie = ioctl_entries;
while (ie->target_cmd != 0) {
if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
TARGET_IOC_SIZEMASK) {
arg_type = ie->arg_type;
if (arg_type[0] != TYPE_PTR) {
fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
ie->target_cmd);
exit(1);
}
arg_type++;
size = thunk_type_size(arg_type, 0);
ie->target_cmd = (ie->target_cmd &
~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
(size << TARGET_IOC_SIZESHIFT);
}
/* automatic consistency check if same arch */
#if defined(__i386__) && defined(TARGET_I386)
if (ie->target_cmd != ie->host_cmd) {
fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
ie->target_cmd, ie->host_cmd);
}
#endif
ie++;
}
}
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,