Commit 2ab83ea7849c2a113ab3ebf0c973435117ddf2d0

Authored by bellard
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,
... ...