Commit 263466f53aa70597b48b415a3a49d6f2e4511f77
1 parent
1e2bed4f
This patch cleans up target_mach_msg_trap(), removes unuseful do_pread, begins …
…sysctl implementation and implements fcntl (Pierre d'Herbemont). git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2388 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
282 additions
and
70 deletions
darwin-user/syscall.c
| ... | ... | @@ -23,9 +23,10 @@ |
| 23 | 23 | #include <stdlib.h> |
| 24 | 24 | #include <errno.h> |
| 25 | 25 | |
| 26 | -#include <mach/message.h> | |
| 26 | +#include <mach/host_info.h> | |
| 27 | 27 | #include <mach/mach.h> |
| 28 | 28 | #include <mach/mach_time.h> |
| 29 | +#include <mach/message.h> | |
| 29 | 30 | |
| 30 | 31 | #include <pthread.h> |
| 31 | 32 | #include <dirent.h> |
| ... | ... | @@ -208,15 +209,14 @@ static inline void print_mach_msg_return(mach_msg_return_t ret) |
| 208 | 209 | else |
| 209 | 210 | { |
| 210 | 211 | for( i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) { |
| 211 | - if(msg_name[0].code & ret) { | |
| 212 | - DPRINTF("%s ", msg_name[0].name); | |
| 212 | + if(msg_name[i].code == ret) { | |
| 213 | + DPRINTF("%s\n", msg_name[i].name); | |
| 213 | 214 | found = 1; |
| 215 | + break; | |
| 214 | 216 | } |
| 215 | 217 | } |
| 216 | 218 | if(!found) |
| 217 | 219 | qerror("unknow mach message ret code %d\n", ret); |
| 218 | - else | |
| 219 | - DPRINTF("\n"); | |
| 220 | 220 | } |
| 221 | 221 | } |
| 222 | 222 | |
| ... | ... | @@ -235,11 +235,10 @@ struct complex_msg { |
| 235 | 235 | mach_msg_body_t body; |
| 236 | 236 | }; |
| 237 | 237 | |
| 238 | -static inline void * swap_mach_msg_body(struct complex_msg *complex_msg, int bswap) | |
| 238 | +static inline void swap_mach_msg_body(struct complex_msg *complex_msg, int bswap) | |
| 239 | 239 | { |
| 240 | 240 | mach_msg_port_descriptor_t *descr = (mach_msg_port_descriptor_t *)(complex_msg+1); |
| 241 | 241 | int i,j; |
| 242 | - void *additional_data; | |
| 243 | 242 | |
| 244 | 243 | if(bswap == bswap_in) |
| 245 | 244 | tswap32s(&complex_msg->body.msgh_descriptor_count); |
| ... | ... | @@ -292,41 +291,41 @@ static inline void * swap_mach_msg_body(struct complex_msg *complex_msg, int bsw |
| 292 | 291 | } |
| 293 | 292 | if(bswap == bswap_out) |
| 294 | 293 | tswap32s(&complex_msg->body.msgh_descriptor_count); |
| 295 | - additional_data = descr; | |
| 296 | - return additional_data; | |
| 294 | +} | |
| 295 | + | |
| 296 | +static inline void swap_mach_msg(mach_msg_header_t *hdr, int bswap) | |
| 297 | +{ | |
| 298 | + if (bswap == bswap_out && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) | |
| 299 | + swap_mach_msg_body((struct complex_msg *)hdr, bswap); | |
| 300 | + | |
| 301 | + swap_mach_msg_header(hdr); | |
| 302 | + | |
| 303 | + if (bswap == bswap_in && hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) | |
| 304 | + swap_mach_msg_body((struct complex_msg *)hdr, bswap); | |
| 297 | 305 | } |
| 298 | 306 | |
| 299 | 307 | static inline uint32_t target_mach_msg_trap( |
| 300 | 308 | mach_msg_header_t *hdr, uint32_t options, uint32_t send_size, |
| 301 | - uint32_t rcv_size, uint32_t rcv_name, uint32_t time_out, uint32_t notify ) | |
| 309 | + uint32_t rcv_size, uint32_t rcv_name, uint32_t time_out, uint32_t notify) | |
| 302 | 310 | { |
| 303 | - extern int mach_msg_trap(mach_msg_header_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); | |
| 311 | + extern int mach_msg_trap(mach_msg_header_t *, mach_msg_option_t, | |
| 312 | + mach_msg_size_t, mach_msg_size_t, mach_port_t, | |
| 313 | + mach_msg_timeout_t, mach_port_t); | |
| 304 | 314 | mach_msg_audit_trailer_t *trailer; |
| 305 | 315 | mach_msg_id_t msg_id; |
| 306 | 316 | uint32_t ret = 0; |
| 307 | - char *additional_data; | |
| 308 | 317 | int i; |
| 309 | 318 | |
| 310 | - swap_mach_msg_header(hdr); | |
| 311 | - | |
| 312 | - print_description_msg_header(hdr); | |
| 319 | + swap_mach_msg(hdr, bswap_in); | |
| 313 | 320 | |
| 314 | 321 | msg_id = hdr->msgh_id; |
| 315 | 322 | |
| 316 | - if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) | |
| 317 | - additional_data = swap_mach_msg_body((struct complex_msg *)hdr, bswap_in); | |
| 318 | - else | |
| 319 | - additional_data = (void*)(hdr+1); | |
| 323 | + print_description_msg_header(hdr); | |
| 320 | 324 | |
| 321 | 325 | ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify); |
| 322 | 326 | |
| 323 | 327 | print_mach_msg_return(ret); |
| 324 | 328 | |
| 325 | - if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) | |
| 326 | - additional_data = swap_mach_msg_body((struct complex_msg *)hdr, bswap_out); | |
| 327 | - else | |
| 328 | - additional_data = (void*)(hdr+1); | |
| 329 | - | |
| 330 | 329 | if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) ) |
| 331 | 330 | { |
| 332 | 331 | /* XXX: the kernel always return the full trailer with MACH_SEND_MSG, so we should |
| ... | ... | @@ -368,33 +367,20 @@ static inline uint32_t target_mach_msg_trap( |
| 368 | 367 | case 200: /* host_info */ |
| 369 | 368 | { |
| 370 | 369 | mig_reply_error_t *err = (mig_reply_error_t *)hdr; |
| 371 | - struct { | |
| 372 | - uint32_t unknow1; | |
| 373 | - uint32_t maxcpu; | |
| 374 | - uint32_t numcpu; | |
| 375 | - uint32_t memsize; | |
| 376 | - uint32_t cpu_type; | |
| 377 | - uint32_t cpu_subtype; | |
| 378 | - } *data = (void *)(err+1); | |
| 379 | - | |
| 380 | - DPRINTF("maxcpu = 0x%x\n", data->maxcpu); | |
| 381 | - DPRINTF("numcpu = 0x%x\n", data->maxcpu); | |
| 382 | - DPRINTF("memsize = 0x%x\n", data->memsize); | |
| 370 | + struct host_basic_info *data = (void *)(err+1); | |
| 371 | + | |
| 372 | + DPRINTF("maxcpu = 0x%x\n", data->max_cpus); | |
| 373 | + DPRINTF("numcpu = 0x%x\n", data->avail_cpus); | |
| 374 | + DPRINTF("memsize = 0x%x\n", data->memory_size); | |
| 383 | 375 | |
| 384 | 376 | #if defined(TARGET_I386) |
| 385 | 377 | data->cpu_type = CPU_TYPE_I386; |
| 386 | 378 | DPRINTF("cpu_type changed to 0x%x(i386)\n", data->cpu_type); |
| 387 | -#elif defined(TARGET_PPC) | |
| 388 | - data->cpu_type = CPU_TYPE_POWERPC; | |
| 389 | - DPRINTF("cpu_type changed to 0x%x(ppc)\n", data->cpu_type); | |
| 390 | -#else | |
| 391 | -# error target not supported | |
| 392 | -#endif | |
| 393 | - | |
| 394 | -#if defined(TARGET_I386) | |
| 395 | 379 | data->cpu_subtype = CPU_SUBTYPE_PENT; |
| 396 | 380 | DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype); |
| 397 | 381 | #elif defined(TARGET_PPC) |
| 382 | + data->cpu_type = CPU_TYPE_POWERPC; | |
| 383 | + DPRINTF("cpu_type changed to 0x%x(ppc)\n", data->cpu_type); | |
| 398 | 384 | data->cpu_subtype = CPU_SUBTYPE_POWERPC_750; |
| 399 | 385 | DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype); |
| 400 | 386 | #else |
| ... | ... | @@ -413,7 +399,7 @@ static inline uint32_t target_mach_msg_trap( |
| 413 | 399 | default: break; |
| 414 | 400 | } |
| 415 | 401 | |
| 416 | - swap_mach_msg_header(hdr); | |
| 402 | + swap_mach_msg(hdr, bswap_out); | |
| 417 | 403 | |
| 418 | 404 | return ret; |
| 419 | 405 | } |
| ... | ... | @@ -827,19 +813,29 @@ long do_fstat(uint32_t arg1, struct stat * arg2); |
| 827 | 813 | long do_lstat(char * arg1, struct stat * arg2); |
| 828 | 814 | long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4); |
| 829 | 815 | long do_lseek(void *cpu_env, int num); |
| 830 | -long do___sysctl(void * arg1, uint32_t arg2, void * arg3, void * arg4, void * arg5, size_t arg6); | |
| 816 | +long do___sysctl(int * name, uint32_t namelen, void * oldp, size_t * oldlenp, void * newp, size_t newlen /* ignored */); | |
| 831 | 817 | long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5); |
| 832 | 818 | long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, void * arg5, void * arg6, void* arg7, uint32_t arg8); |
| 819 | +long do_fcntl(int fd, int cmd, int arg); | |
| 833 | 820 | |
| 834 | 821 | long no_syscall(void *cpu_env, int num); |
| 835 | 822 | |
| 836 | 823 | long do_pread(uint32_t arg1, void * arg2, size_t arg3, off_t arg4) |
| 837 | 824 | { |
| 838 | - //DPRINTF("0x%x, 0x%x, 0x%x, 0x%llx\n", arg1, arg2, arg3, arg4); | |
| 839 | - long ret = (pread(arg1, arg2, arg3, arg4)); | |
| 840 | - DPRINTF("0x%x\n", *(int*)arg2); | |
| 825 | + DPRINTF("0x%x, %p, 0x%lx, 0x%llx\n", arg1, arg2, arg3, arg4); | |
| 826 | + long ret = pread(arg1, arg2, arg3, arg4); | |
| 827 | + return ret; | |
| 828 | +} | |
| 829 | + | |
| 830 | +long do_read(int d, void *buf, size_t nbytes) | |
| 831 | +{ | |
| 832 | + DPRINTF("0x%x, %p, 0x%lx\n", d, buf, nbytes); | |
| 833 | + long ret = get_errno(read(d, buf, nbytes)); | |
| 834 | + if(!is_error(ret)) | |
| 835 | + DPRINTF("%x\n", *(uint32_t*)buf); | |
| 841 | 836 | return ret; |
| 842 | 837 | } |
| 838 | + | |
| 843 | 839 | long unimpl_unix_syscall(void *cpu_env, int num); |
| 844 | 840 | |
| 845 | 841 | typedef long (*syscall_function_t)(void *cpu_env, int num); |
| ... | ... | @@ -1199,33 +1195,163 @@ long do_lseek(void *cpu_env, int num) |
| 1199 | 1195 | return get_errno(ret); |
| 1200 | 1196 | } |
| 1201 | 1197 | |
| 1202 | -long do___sysctl(void * arg1, uint32_t arg2, void * arg3, void * arg4, void * arg5, size_t arg6) | |
| 1198 | +void no_swap(void * oldp, int size) | |
| 1199 | +{ | |
| 1200 | +} | |
| 1201 | + | |
| 1202 | +void sysctl_tswap32s(void * oldp, int size) | |
| 1203 | +{ | |
| 1204 | + tswap32s(oldp); | |
| 1205 | +} | |
| 1206 | + | |
| 1207 | +void bswap_oid(uint32_t * oldp, int size) | |
| 1208 | +{ | |
| 1209 | + int count = size / sizeof(int); | |
| 1210 | + int i = 0; | |
| 1211 | + do { tswap32s(oldp + i); } while (++i < count); | |
| 1212 | +} | |
| 1213 | + | |
| 1214 | +void sysctl_usrstack(uint32_t * oldp, int size) | |
| 1215 | +{ | |
| 1216 | + DPRINTF("sysctl_usrstack: 0x%x\n", *oldp); | |
| 1217 | + tswap32s(oldp); | |
| 1218 | +} | |
| 1219 | + | |
| 1220 | +void sysctl_ncpu(uint32_t * ncpu, int size) | |
| 1221 | +{ | |
| 1222 | + *ncpu = 0x1; | |
| 1223 | + DPRINTF("sysctl_ncpu: 0x%x\n", *ncpu); | |
| 1224 | + tswap32s(ncpu); | |
| 1225 | +} | |
| 1226 | + | |
| 1227 | +void sysctl_exec(char * exec, int size) | |
| 1228 | +{ | |
| 1229 | + DPRINTF("sysctl_exec: %s\n", exec); | |
| 1230 | +} | |
| 1231 | + | |
| 1232 | +void sysctl_translate(char * exec, int size) | |
| 1233 | +{ | |
| 1234 | + DPRINTF("sysctl_translate: %s\n", exec); | |
| 1235 | +} | |
| 1236 | + | |
| 1237 | +struct sysctl_dir { | |
| 1238 | + int num; | |
| 1239 | + const char * name; | |
| 1240 | + void (*swap_func)(void *, int); | |
| 1241 | + struct sysctl_dir *childs; | |
| 1242 | +}; | |
| 1243 | + | |
| 1244 | +#define ENTRYD(num, name, childs) { num, name, NULL, childs } | |
| 1245 | +#define ENTRYE(num, name, func) { num, name, (void (*)(void *, int))func, NULL } | |
| 1246 | +struct sysctl_dir sysctls_unspec[] = { | |
| 1247 | + ENTRYE(3, "oip", bswap_oid), | |
| 1248 | + { 0, NULL, NULL, NULL } | |
| 1249 | +}; | |
| 1250 | + | |
| 1251 | +struct sysctl_dir sysctls_kern[] = { | |
| 1252 | + ENTRYE(KERN_TRANSLATE, "translate", sysctl_translate), /* 44 */ | |
| 1253 | + ENTRYE(KERN_EXEC, "exec", sysctl_exec), /* 45 */ | |
| 1254 | + ENTRYE(KERN_USRSTACK32, "KERN_USRSTACK32", sysctl_usrstack), /* 35 */ | |
| 1255 | + ENTRYE(KERN_SHREG_PRIVATIZABLE, "KERN_SHREG_PRIVATIZABLE", sysctl_tswap32s), /* 54 */ | |
| 1256 | + { 0, NULL, NULL, NULL } | |
| 1257 | +}; | |
| 1258 | + | |
| 1259 | +struct sysctl_dir sysctls_hw[] = { | |
| 1260 | + ENTRYE(HW_NCPU, "ncpud", sysctl_tswap32s), | |
| 1261 | + ENTRYE(104, "104", no_swap), | |
| 1262 | + ENTRYE(105, "105", no_swap), | |
| 1263 | + { 0, NULL, NULL, NULL } | |
| 1264 | +}; | |
| 1265 | + | |
| 1266 | +struct sysctl_dir sysctls[] = { | |
| 1267 | + ENTRYD(CTL_UNSPEC, "unspec", sysctls_unspec), | |
| 1268 | + ENTRYD(CTL_KERN, "kern", sysctls_kern), | |
| 1269 | + ENTRYD(CTL_HW, "hw", sysctls_hw ), | |
| 1270 | + { 0, NULL, NULL, NULL } | |
| 1271 | +}; | |
| 1272 | + | |
| 1273 | +#undef ENTRYE | |
| 1274 | +#undef ENTRYD | |
| 1275 | + | |
| 1276 | +static inline struct sysctl_dir * get_sysctl_entry_for_mib(int mib, struct sysctl_dir * sysctl_elmt) | |
| 1277 | +{ | |
| 1278 | + if(!sysctl_elmt) | |
| 1279 | + return NULL; | |
| 1280 | + for(; sysctl_elmt->name != NULL ; sysctl_elmt++) { | |
| 1281 | + if(sysctl_elmt->num == mib) | |
| 1282 | + return sysctl_elmt; | |
| 1283 | + } | |
| 1284 | + return NULL; | |
| 1285 | +} | |
| 1286 | + | |
| 1287 | +static inline long bswap_syctl(int * mib, int count, void *buf, int size) | |
| 1288 | +{ | |
| 1289 | + int i; | |
| 1290 | + struct sysctl_dir * sysctl = sysctls; | |
| 1291 | + struct sysctl_dir * ret = NULL; | |
| 1292 | + | |
| 1293 | + for(i = 0; i < count; i++) { | |
| 1294 | + | |
| 1295 | + if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))) { | |
| 1296 | + gemu_log("bswap_syctl: can't find mib %d\n", mib[i]); | |
| 1297 | + return -ENOTDIR; | |
| 1298 | + } | |
| 1299 | + if(!(sysctl = sysctl->childs)) | |
| 1300 | + break; | |
| 1301 | + } | |
| 1302 | + | |
| 1303 | + if(ret->childs) | |
| 1304 | + qerror("we shouldn't have a directory element\n"); | |
| 1305 | + | |
| 1306 | + ret->swap_func(buf, size); | |
| 1307 | + return 0; | |
| 1308 | +} | |
| 1309 | + | |
| 1310 | +static inline void print_syctl(int * mib, int count) | |
| 1311 | +{ | |
| 1312 | + int i; | |
| 1313 | + struct sysctl_dir * sysctl = sysctls; | |
| 1314 | + struct sysctl_dir * ret = NULL; | |
| 1315 | + | |
| 1316 | + for(i = 0; i < count; i++) { | |
| 1317 | + if(!(ret = sysctl = get_sysctl_entry_for_mib(mib[i], sysctl))){ | |
| 1318 | + gemu_log("print_syctl: can't find mib %d\n", mib[i]); | |
| 1319 | + return; | |
| 1320 | + } | |
| 1321 | + DPRINTF("%s.", sysctl->name); | |
| 1322 | + if(!(sysctl = sysctl->childs)) | |
| 1323 | + break; | |
| 1324 | + } | |
| 1325 | + DPRINTF("\n"); | |
| 1326 | +} | |
| 1327 | + | |
| 1328 | +long do___sysctl(int * name, uint32_t namelen, void * oldp, size_t * oldlenp, void * newp, size_t newlen /* ignored */) | |
| 1203 | 1329 | { |
| 1204 | 1330 | long ret = 0; |
| 1205 | 1331 | int i; |
| 1206 | 1332 | DPRINTF("sysctl(%p, 0x%x, %p, %p, %p, 0x%lx)\n", |
| 1207 | - arg1, arg2, arg3, arg4, arg5, arg6); | |
| 1208 | - if(arg1) { | |
| 1333 | + name, namelen, oldp, oldlenp, newp, newlen); | |
| 1334 | + if(name) { | |
| 1209 | 1335 | i = 0; |
| 1210 | - do { *((int *) arg1 + i) = tswap32(*((int *) arg1 + i)); } while (++i < arg2); | |
| 1336 | + do { tswap32s( name + i); } while (++i < namelen); | |
| 1337 | + print_syctl(name, namelen); | |
| 1338 | + //bswap_syctl(name, namelen, newp, newlen); | |
| 1339 | + tswap32s((uint32_t*)oldlenp); | |
| 1211 | 1340 | } |
| 1341 | + | |
| 1342 | + if(name) /* Sometimes sysctl is called with no arg1, ignore */ | |
| 1343 | + ret = get_errno(sysctl(name, namelen, oldp, oldlenp, newp, newlen)); | |
| 1212 | 1344 | |
| 1213 | - if(arg4) | |
| 1214 | - *(int *) arg4 = tswap32(*(int *) arg4); | |
| 1215 | - if(arg1) | |
| 1216 | - ret = get_errno(sysctl((void *)arg1, arg2, (void *)arg3, (void *)arg4, (void *)arg5, arg6)); | |
| 1217 | - | |
| 1218 | - if ((ret == 0) && (arg2 == 2) && (*((int *) arg1) == 0) && (*((int *) arg1 + 1) == 3)) { | |
| 1219 | - /* The output here is the new id - we need to swap it so it can be passed | |
| 1220 | - back in (and then unswapped) */ | |
| 1221 | - int count = (*(int *) arg4) / sizeof(int); | |
| 1222 | - i = 0; | |
| 1223 | - do { | |
| 1224 | - *((int *) arg3 + i) = tswap32(*((int *) arg3 + i)); | |
| 1225 | - } while (++i < count); | |
| 1345 | + if (!is_error(ret) && bswap_syctl(name, namelen, oldp, *oldlenp) != 0) { | |
| 1346 | + return -ENOTDIR; | |
| 1226 | 1347 | } |
| 1227 | - *(int *) arg4 = tswap32(*(int *) arg4); | |
| 1348 | + if(name) { | |
| 1349 | + //bswap_syctl(name, namelen, newp, newlen); | |
| 1350 | + tswap32s((uint32_t*)oldlenp); | |
| 1228 | 1351 | |
| 1352 | + i = 0; | |
| 1353 | + do { tswap32s( name + i); } while (++i < namelen); | |
| 1354 | + } | |
| 1229 | 1355 | return ret; |
| 1230 | 1356 | } |
| 1231 | 1357 | |
| ... | ... | @@ -1235,7 +1361,8 @@ long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32 |
| 1235 | 1361 | long ret; |
| 1236 | 1362 | |
| 1237 | 1363 | #if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__) |
| 1238 | - qerror("SYS_getdirentriesattr unimplemented\n"); | |
| 1364 | + gemu_log("SYS_getdirentriesattr unimplemented\n"); | |
| 1365 | + return -ENOTSUP; | |
| 1239 | 1366 | #endif |
| 1240 | 1367 | /* XXX: don't let the %s stay in there */ |
| 1241 | 1368 | DPRINTF("getattrlist(%s, %p, %p, 0x%x, 0x%x)\n", |
| ... | ... | @@ -1268,6 +1395,91 @@ long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, |
| 1268 | 1395 | (unsigned long *)arg7, arg8)); |
| 1269 | 1396 | } |
| 1270 | 1397 | |
| 1398 | +static inline void bswap_flock(struct flock *f) | |
| 1399 | +{ | |
| 1400 | + tswap64s(&f->l_start); | |
| 1401 | + tswap64s(&f->l_len); | |
| 1402 | + tswap32s(&f->l_pid); | |
| 1403 | + tswap16s(&f->l_type); | |
| 1404 | + tswap16s(&f->l_whence); | |
| 1405 | +} | |
| 1406 | + | |
| 1407 | +static inline void bswap_fstore(struct fstore *f) | |
| 1408 | +{ | |
| 1409 | + tswap32s(&f->fst_flags); | |
| 1410 | + tswap32s(&f->fst_posmode); | |
| 1411 | + tswap64s(&f->fst_offset); | |
| 1412 | + tswap64s(&f->fst_length); | |
| 1413 | + tswap64s(&f->fst_bytesalloc); | |
| 1414 | +} | |
| 1415 | + | |
| 1416 | +static inline void bswap_radvisory(struct radvisory *f) | |
| 1417 | +{ | |
| 1418 | + tswap64s(&f->ra_offset); | |
| 1419 | + tswap32s(&f->ra_count); | |
| 1420 | +} | |
| 1421 | + | |
| 1422 | +static inline void bswap_fbootstraptransfer(struct fbootstraptransfer *f) | |
| 1423 | +{ | |
| 1424 | + tswap64s(&f->fbt_offset); | |
| 1425 | + tswap32s((uint32_t*)&f->fbt_length); | |
| 1426 | + tswap32s((uint32_t*)&f->fbt_buffer); /* XXX: this is a ptr */ | |
| 1427 | +} | |
| 1428 | + | |
| 1429 | +static inline void bswap_log2phys(struct log2phys *f) | |
| 1430 | +{ | |
| 1431 | + tswap32s(&f->l2p_flags); | |
| 1432 | + tswap64s(&f->l2p_contigbytes); | |
| 1433 | + tswap64s(&f->l2p_devoffset); | |
| 1434 | +} | |
| 1435 | + | |
| 1436 | +static inline void bswap_fcntl_arg(int cmd, void * arg) | |
| 1437 | +{ | |
| 1438 | + switch(cmd) | |
| 1439 | + { | |
| 1440 | + case F_DUPFD: | |
| 1441 | + case F_GETFD: | |
| 1442 | + case F_SETFD: | |
| 1443 | + case F_GETFL: | |
| 1444 | + case F_SETFL: | |
| 1445 | + case F_GETOWN: | |
| 1446 | + case F_SETOWN: | |
| 1447 | + case F_SETSIZE: | |
| 1448 | + case F_RDAHEAD: | |
| 1449 | + case F_FULLFSYNC: | |
| 1450 | + break; | |
| 1451 | + case F_GETLK: | |
| 1452 | + case F_SETLK: | |
| 1453 | + case F_SETLKW: | |
| 1454 | + bswap_flock(arg); | |
| 1455 | + break; | |
| 1456 | + case F_PREALLOCATE: | |
| 1457 | + bswap_fstore(arg); | |
| 1458 | + break; | |
| 1459 | + case F_RDADVISE: | |
| 1460 | + bswap_radvisory(arg); | |
| 1461 | + break; | |
| 1462 | + case F_READBOOTSTRAP: | |
| 1463 | + case F_WRITEBOOTSTRAP: | |
| 1464 | + bswap_fbootstraptransfer(arg); | |
| 1465 | + break; | |
| 1466 | + case F_LOG2PHYS: | |
| 1467 | + bswap_log2phys(arg); | |
| 1468 | + break; | |
| 1469 | + default: | |
| 1470 | + gemu_log("unknow cmd in fcntl\n"); | |
| 1471 | + } | |
| 1472 | +} | |
| 1473 | + | |
| 1474 | +long do_fcntl(int fd, int cmd, int arg) | |
| 1475 | +{ | |
| 1476 | + long ret; | |
| 1477 | + bswap_fcntl_arg(cmd, (void *)arg); | |
| 1478 | + ret = get_errno(fcntl(fd, cmd, arg)); | |
| 1479 | + if(!is_error(ret)) | |
| 1480 | + bswap_fcntl_arg(cmd, (void *)arg); | |
| 1481 | + return ret; | |
| 1482 | +} | |
| 1271 | 1483 | |
| 1272 | 1484 | long no_syscall(void *cpu_env, int num) |
| 1273 | 1485 | { | ... | ... |
darwin-user/syscalls.h
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | ENTRY("syscall", SYS_syscall, do_unix_syscall_indirect, 0, CALL_INDIRECT, VOID) /* 0 indirect syscall */ |
| 4 | 4 | ENTRY("exit", SYS_exit, do_exit, 1, CALL_DIRECT, INT) /* 1 */ |
| 5 | 5 | ENTRY("fork", SYS_fork, fork, 0, CALL_NOERRNO, VOID) /* 2 */ |
| 6 | - ENTRY("read", SYS_read, read, 3, CALL_DIRECT, INT, PTR, SIZE) /* 3 */ | |
| 6 | + ENTRY("read", SYS_read, do_read, 3, CALL_DIRECT, INT, PTR, SIZE) /* 3 */ | |
| 7 | 7 | ENTRY("write", SYS_write, write, 3, CALL_DIRECT, INT, PTR, SIZE) /* 4 */ |
| 8 | 8 | ENTRY("open", SYS_open, do_open, 3, CALL_DIRECT, PTR, INT, INT) /* 5 */ |
| 9 | 9 | ENTRY("close", SYS_close, close, 1, CALL_DIRECT, INT) /* 6 */ |
| ... | ... | @@ -92,7 +92,7 @@ |
| 92 | 92 | ENTRY("getdtablesize", SYS_getdtablesize, getdtablesize, 0, CALL_DIRECT, VOID) /* 89 */ |
| 93 | 93 | ENTRY("dup2", SYS_dup2, dup2, 2, CALL_DIRECT, INT, INT) /* 90 */ |
| 94 | 94 | ENTRY("", 91, no_syscall, 0, CALL_INDIRECT, VOID) /* 91 old getdopt */ |
| 95 | - ENTRY("fcntl", SYS_fcntl, fcntl, 3, CALL_DIRECT, INT, INT, INT) /* 92 */ | |
| 95 | + ENTRY("fcntl", SYS_fcntl, do_fcntl, 3, CALL_DIRECT, INT, INT, INT) /* 92 */ | |
| 96 | 96 | ENTRY("select", SYS_select, select, 5, CALL_DIRECT, INT, PTR, PTR, PTR, PTR) /* 93 */ |
| 97 | 97 | ENTRY("", 94, no_syscall, 0, CALL_INDIRECT, VOID) /* 94 old setdopt */ |
| 98 | 98 | ENTRY("fsync", SYS_fsync, fsync, 1, CALL_DIRECT, INT) /* 95 */ | ... | ... |