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:
parent
2437490100
commit
2ab83ea784
@ -68,11 +68,6 @@
|
|||||||
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
|
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
|
||||||
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, 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_uname __NR_uname
|
||||||
#define __NR_sys_getcwd1 __NR_getcwd
|
#define __NR_sys_getcwd1 __NR_getcwd
|
||||||
#define __NR_sys_statfs __NR_statfs
|
#define __NR_sys_statfs __NR_statfs
|
||||||
@ -702,8 +697,8 @@ enum {
|
|||||||
#undef STRUCT_SPECIAL
|
#undef STRUCT_SPECIAL
|
||||||
|
|
||||||
typedef struct IOCTLEntry {
|
typedef struct IOCTLEntry {
|
||||||
int target_cmd;
|
unsigned int target_cmd;
|
||||||
int host_cmd;
|
unsigned int host_cmd;
|
||||||
const char *name;
|
const char *name;
|
||||||
int access;
|
int access;
|
||||||
const argtype arg_type[5];
|
const argtype arg_type[5];
|
||||||
@ -715,7 +710,7 @@ typedef struct IOCTLEntry {
|
|||||||
|
|
||||||
#define MAX_STRUCT_SIZE 4096
|
#define MAX_STRUCT_SIZE 4096
|
||||||
|
|
||||||
const IOCTLEntry ioctl_entries[] = {
|
IOCTLEntry ioctl_entries[] = {
|
||||||
#define IOCTL(cmd, access, types...) \
|
#define IOCTL(cmd, access, types...) \
|
||||||
{ TARGET_ ## cmd, cmd, #cmd, access, { types } },
|
{ TARGET_ ## cmd, cmd, #cmd, access, { types } },
|
||||||
#include "ioctls.h"
|
#include "ioctls.h"
|
||||||
@ -970,7 +965,7 @@ static bitmask_transtbl mmap_flags_tbl[] = {
|
|||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TARGET_I386
|
#if defined(TARGET_I386)
|
||||||
|
|
||||||
/* NOTE: there is really one LDT for all the threads */
|
/* NOTE: there is really one LDT for all the threads */
|
||||||
uint8_t *ldt_table;
|
uint8_t *ldt_table;
|
||||||
@ -1087,28 +1082,28 @@ int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* defined(TARGET_I386) */
|
||||||
|
|
||||||
/* this stack is the equivalent of the kernel stack associated with a
|
/* this stack is the equivalent of the kernel stack associated with a
|
||||||
thread/process */
|
thread/process */
|
||||||
#define NEW_STACK_SIZE 8192
|
#define NEW_STACK_SIZE 8192
|
||||||
|
|
||||||
static int clone_func(void *arg)
|
static int clone_func(void *arg)
|
||||||
{
|
{
|
||||||
CPUX86State *env = arg;
|
CPUState *env = arg;
|
||||||
cpu_loop(env);
|
cpu_loop(env);
|
||||||
/* never exits */
|
/* never exits */
|
||||||
return 0;
|
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;
|
int ret;
|
||||||
TaskState *ts;
|
TaskState *ts;
|
||||||
uint8_t *new_stack;
|
uint8_t *new_stack;
|
||||||
CPUX86State *new_env;
|
CPUState *new_env;
|
||||||
|
|
||||||
if (flags & CLONE_VM) {
|
if (flags & CLONE_VM) {
|
||||||
if (!newsp)
|
|
||||||
newsp = env->regs[R_ESP];
|
|
||||||
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
|
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
|
||||||
memset(ts, 0, sizeof(TaskState));
|
memset(ts, 0, sizeof(TaskState));
|
||||||
new_stack = ts->stack;
|
new_stack = ts->stack;
|
||||||
@ -1117,10 +1112,21 @@ int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
|
|||||||
ts->next = first_task_state;
|
ts->next = first_task_state;
|
||||||
first_task_state = ts;
|
first_task_state = ts;
|
||||||
/* we create a new CPU instance. */
|
/* we create a new CPU instance. */
|
||||||
new_env = cpu_x86_init();
|
new_env = cpu_init();
|
||||||
memcpy(new_env, env, sizeof(CPUX86State));
|
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_ESP] = newsp;
|
||||||
new_env->regs[R_EAX] = 0;
|
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;
|
new_env->opaque = ts;
|
||||||
#ifdef __ia64__
|
#ifdef __ia64__
|
||||||
ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static long do_fcntl(int fd, int cmd, unsigned long arg)
|
static long do_fcntl(int fd, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct flock fl;
|
struct flock fl;
|
||||||
@ -1188,11 +1192,43 @@ static long do_fcntl(int fd, int cmd, unsigned long arg)
|
|||||||
|
|
||||||
void syscall_init(void)
|
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(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);
|
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
|
||||||
#include "syscall_types.h"
|
#include "syscall_types.h"
|
||||||
#undef STRUCT
|
#undef STRUCT
|
||||||
#undef STRUCT_SPECIAL
|
#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,
|
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||||
|
Loading…
Reference in New Issue
Block a user