Commit 2ab83ea7849c2a113ab3ebf0c973435117ddf2d0
1 parent
24374901
automatic ioctl number conversion - minimum ARM fork() support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@240 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
54 additions
and
18 deletions
linux-user/syscall.c
... | ... | @@ -68,11 +68,6 @@ |
68 | 68 | #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) |
69 | 69 | #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) |
70 | 70 | |
71 | -void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | |
72 | -void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); | |
73 | -long do_sigreturn(CPUX86State *env); | |
74 | -long do_rt_sigreturn(CPUX86State *env); | |
75 | - | |
76 | 71 | #define __NR_sys_uname __NR_uname |
77 | 72 | #define __NR_sys_getcwd1 __NR_getcwd |
78 | 73 | #define __NR_sys_statfs __NR_statfs |
... | ... | @@ -702,8 +697,8 @@ enum { |
702 | 697 | #undef STRUCT_SPECIAL |
703 | 698 | |
704 | 699 | typedef struct IOCTLEntry { |
705 | - int target_cmd; | |
706 | - int host_cmd; | |
700 | + unsigned int target_cmd; | |
701 | + unsigned int host_cmd; | |
707 | 702 | const char *name; |
708 | 703 | int access; |
709 | 704 | const argtype arg_type[5]; |
... | ... | @@ -715,7 +710,7 @@ typedef struct IOCTLEntry { |
715 | 710 | |
716 | 711 | #define MAX_STRUCT_SIZE 4096 |
717 | 712 | |
718 | -const IOCTLEntry ioctl_entries[] = { | |
713 | +IOCTLEntry ioctl_entries[] = { | |
719 | 714 | #define IOCTL(cmd, access, types...) \ |
720 | 715 | { TARGET_ ## cmd, cmd, #cmd, access, { types } }, |
721 | 716 | #include "ioctls.h" |
... | ... | @@ -970,7 +965,7 @@ static bitmask_transtbl mmap_flags_tbl[] = { |
970 | 965 | { 0, 0, 0, 0 } |
971 | 966 | }; |
972 | 967 | |
973 | -#ifdef TARGET_I386 | |
968 | +#if defined(TARGET_I386) | |
974 | 969 | |
975 | 970 | /* NOTE: there is really one LDT for all the threads */ |
976 | 971 | uint8_t *ldt_table; |
... | ... | @@ -1087,28 +1082,28 @@ int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount |
1087 | 1082 | return ret; |
1088 | 1083 | } |
1089 | 1084 | |
1085 | +#endif /* defined(TARGET_I386) */ | |
1086 | + | |
1090 | 1087 | /* this stack is the equivalent of the kernel stack associated with a |
1091 | 1088 | thread/process */ |
1092 | 1089 | #define NEW_STACK_SIZE 8192 |
1093 | 1090 | |
1094 | 1091 | static int clone_func(void *arg) |
1095 | 1092 | { |
1096 | - CPUX86State *env = arg; | |
1093 | + CPUState *env = arg; | |
1097 | 1094 | cpu_loop(env); |
1098 | 1095 | /* never exits */ |
1099 | 1096 | return 0; |
1100 | 1097 | } |
1101 | 1098 | |
1102 | -int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp) | |
1099 | +int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) | |
1103 | 1100 | { |
1104 | 1101 | int ret; |
1105 | 1102 | TaskState *ts; |
1106 | 1103 | uint8_t *new_stack; |
1107 | - CPUX86State *new_env; | |
1104 | + CPUState *new_env; | |
1108 | 1105 | |
1109 | 1106 | if (flags & CLONE_VM) { |
1110 | - if (!newsp) | |
1111 | - newsp = env->regs[R_ESP]; | |
1112 | 1107 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); |
1113 | 1108 | memset(ts, 0, sizeof(TaskState)); |
1114 | 1109 | new_stack = ts->stack; |
... | ... | @@ -1117,10 +1112,21 @@ int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp) |
1117 | 1112 | ts->next = first_task_state; |
1118 | 1113 | first_task_state = ts; |
1119 | 1114 | /* we create a new CPU instance. */ |
1120 | - new_env = cpu_x86_init(); | |
1121 | - memcpy(new_env, env, sizeof(CPUX86State)); | |
1115 | + new_env = cpu_init(); | |
1116 | + memcpy(new_env, env, sizeof(CPUState)); | |
1117 | +#if defined(TARGET_I386) | |
1118 | + if (!newsp) | |
1119 | + newsp = env->regs[R_ESP]; | |
1122 | 1120 | new_env->regs[R_ESP] = newsp; |
1123 | 1121 | new_env->regs[R_EAX] = 0; |
1122 | +#elif defined(TARGET_ARM) | |
1123 | + if (!newsp) | |
1124 | + newsp = env->regs[13]; | |
1125 | + new_env->regs[13] = newsp; | |
1126 | + new_env->regs[0] = 0; | |
1127 | +#else | |
1128 | +#error unsupported target CPU | |
1129 | +#endif | |
1124 | 1130 | new_env->opaque = ts; |
1125 | 1131 | #ifdef __ia64__ |
1126 | 1132 | 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) |
1136 | 1142 | return ret; |
1137 | 1143 | } |
1138 | 1144 | |
1139 | -#endif | |
1140 | - | |
1141 | 1145 | static long do_fcntl(int fd, int cmd, unsigned long arg) |
1142 | 1146 | { |
1143 | 1147 | struct flock fl; |
... | ... | @@ -1188,11 +1192,43 @@ static long do_fcntl(int fd, int cmd, unsigned long arg) |
1188 | 1192 | |
1189 | 1193 | void syscall_init(void) |
1190 | 1194 | { |
1195 | + IOCTLEntry *ie; | |
1196 | + const argtype *arg_type; | |
1197 | + int size; | |
1198 | + | |
1191 | 1199 | #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); |
1192 | 1200 | #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); |
1193 | 1201 | #include "syscall_types.h" |
1194 | 1202 | #undef STRUCT |
1195 | 1203 | #undef STRUCT_SPECIAL |
1204 | + | |
1205 | + /* we patch the ioctl size if necessary. We rely on the fact that | |
1206 | + no ioctl has all the bits at '1' in the size field */ | |
1207 | + ie = ioctl_entries; | |
1208 | + while (ie->target_cmd != 0) { | |
1209 | + if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) == | |
1210 | + TARGET_IOC_SIZEMASK) { | |
1211 | + arg_type = ie->arg_type; | |
1212 | + if (arg_type[0] != TYPE_PTR) { | |
1213 | + fprintf(stderr, "cannot patch size for ioctl 0x%x\n", | |
1214 | + ie->target_cmd); | |
1215 | + exit(1); | |
1216 | + } | |
1217 | + arg_type++; | |
1218 | + size = thunk_type_size(arg_type, 0); | |
1219 | + ie->target_cmd = (ie->target_cmd & | |
1220 | + ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | | |
1221 | + (size << TARGET_IOC_SIZESHIFT); | |
1222 | + } | |
1223 | + /* automatic consistency check if same arch */ | |
1224 | +#if defined(__i386__) && defined(TARGET_I386) | |
1225 | + if (ie->target_cmd != ie->host_cmd) { | |
1226 | + fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n", | |
1227 | + ie->target_cmd, ie->host_cmd); | |
1228 | + } | |
1229 | +#endif | |
1230 | + ie++; | |
1231 | + } | |
1196 | 1232 | } |
1197 | 1233 | |
1198 | 1234 | long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ... | ... |