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 */ | ... | ... |