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,9 +23,10 @@ | ||
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <errno.h> | 24 | #include <errno.h> |
25 | 25 | ||
26 | -#include <mach/message.h> | 26 | +#include <mach/host_info.h> |
27 | #include <mach/mach.h> | 27 | #include <mach/mach.h> |
28 | #include <mach/mach_time.h> | 28 | #include <mach/mach_time.h> |
29 | +#include <mach/message.h> | ||
29 | 30 | ||
30 | #include <pthread.h> | 31 | #include <pthread.h> |
31 | #include <dirent.h> | 32 | #include <dirent.h> |
@@ -208,15 +209,14 @@ static inline void print_mach_msg_return(mach_msg_return_t ret) | @@ -208,15 +209,14 @@ static inline void print_mach_msg_return(mach_msg_return_t ret) | ||
208 | else | 209 | else |
209 | { | 210 | { |
210 | for( i = 0; i < sizeof(msg_name)/sizeof(msg_name[0]); i++) { | 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 | found = 1; | 214 | found = 1; |
215 | + break; | ||
214 | } | 216 | } |
215 | } | 217 | } |
216 | if(!found) | 218 | if(!found) |
217 | qerror("unknow mach message ret code %d\n", ret); | 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,11 +235,10 @@ struct complex_msg { | ||
235 | mach_msg_body_t body; | 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 | mach_msg_port_descriptor_t *descr = (mach_msg_port_descriptor_t *)(complex_msg+1); | 240 | mach_msg_port_descriptor_t *descr = (mach_msg_port_descriptor_t *)(complex_msg+1); |
241 | int i,j; | 241 | int i,j; |
242 | - void *additional_data; | ||
243 | 242 | ||
244 | if(bswap == bswap_in) | 243 | if(bswap == bswap_in) |
245 | tswap32s(&complex_msg->body.msgh_descriptor_count); | 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,41 +291,41 @@ static inline void * swap_mach_msg_body(struct complex_msg *complex_msg, int bsw | ||
292 | } | 291 | } |
293 | if(bswap == bswap_out) | 292 | if(bswap == bswap_out) |
294 | tswap32s(&complex_msg->body.msgh_descriptor_count); | 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 | static inline uint32_t target_mach_msg_trap( | 307 | static inline uint32_t target_mach_msg_trap( |
300 | mach_msg_header_t *hdr, uint32_t options, uint32_t send_size, | 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 | mach_msg_audit_trailer_t *trailer; | 314 | mach_msg_audit_trailer_t *trailer; |
305 | mach_msg_id_t msg_id; | 315 | mach_msg_id_t msg_id; |
306 | uint32_t ret = 0; | 316 | uint32_t ret = 0; |
307 | - char *additional_data; | ||
308 | int i; | 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 | msg_id = hdr->msgh_id; | 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 | ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify); | 325 | ret = mach_msg_trap(hdr, options, send_size, rcv_size, rcv_name, time_out, notify); |
322 | 326 | ||
323 | print_mach_msg_return(ret); | 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 | if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) ) | 329 | if( (options & MACH_RCV_MSG) && (REQUESTED_TRAILER_SIZE(options) > 0) ) |
331 | { | 330 | { |
332 | /* XXX: the kernel always return the full trailer with MACH_SEND_MSG, so we should | 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,33 +367,20 @@ static inline uint32_t target_mach_msg_trap( | ||
368 | case 200: /* host_info */ | 367 | case 200: /* host_info */ |
369 | { | 368 | { |
370 | mig_reply_error_t *err = (mig_reply_error_t *)hdr; | 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 | #if defined(TARGET_I386) | 376 | #if defined(TARGET_I386) |
385 | data->cpu_type = CPU_TYPE_I386; | 377 | data->cpu_type = CPU_TYPE_I386; |
386 | DPRINTF("cpu_type changed to 0x%x(i386)\n", data->cpu_type); | 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 | data->cpu_subtype = CPU_SUBTYPE_PENT; | 379 | data->cpu_subtype = CPU_SUBTYPE_PENT; |
396 | DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype); | 380 | DPRINTF("cpu_subtype changed to 0x%x(i386_pent)\n", data->cpu_subtype); |
397 | #elif defined(TARGET_PPC) | 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 | data->cpu_subtype = CPU_SUBTYPE_POWERPC_750; | 384 | data->cpu_subtype = CPU_SUBTYPE_POWERPC_750; |
399 | DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype); | 385 | DPRINTF("cpu_subtype changed to 0x%x(ppc_all)\n", data->cpu_subtype); |
400 | #else | 386 | #else |
@@ -413,7 +399,7 @@ static inline uint32_t target_mach_msg_trap( | @@ -413,7 +399,7 @@ static inline uint32_t target_mach_msg_trap( | ||
413 | default: break; | 399 | default: break; |
414 | } | 400 | } |
415 | 401 | ||
416 | - swap_mach_msg_header(hdr); | 402 | + swap_mach_msg(hdr, bswap_out); |
417 | 403 | ||
418 | return ret; | 404 | return ret; |
419 | } | 405 | } |
@@ -827,19 +813,29 @@ long do_fstat(uint32_t arg1, struct stat * arg2); | @@ -827,19 +813,29 @@ long do_fstat(uint32_t arg1, struct stat * arg2); | ||
827 | long do_lstat(char * arg1, struct stat * arg2); | 813 | long do_lstat(char * arg1, struct stat * arg2); |
828 | long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4); | 814 | long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4); |
829 | long do_lseek(void *cpu_env, int num); | 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 | long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5); | 817 | long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32_t arg5); |
832 | long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, void * arg5, void * arg6, void* arg7, uint32_t arg8); | 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 | long no_syscall(void *cpu_env, int num); | 821 | long no_syscall(void *cpu_env, int num); |
835 | 822 | ||
836 | long do_pread(uint32_t arg1, void * arg2, size_t arg3, off_t arg4) | 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 | return ret; | 836 | return ret; |
842 | } | 837 | } |
838 | + | ||
843 | long unimpl_unix_syscall(void *cpu_env, int num); | 839 | long unimpl_unix_syscall(void *cpu_env, int num); |
844 | 840 | ||
845 | typedef long (*syscall_function_t)(void *cpu_env, int num); | 841 | typedef long (*syscall_function_t)(void *cpu_env, int num); |
@@ -1199,33 +1195,163 @@ long do_lseek(void *cpu_env, int num) | @@ -1199,33 +1195,163 @@ long do_lseek(void *cpu_env, int num) | ||
1199 | return get_errno(ret); | 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 | long ret = 0; | 1330 | long ret = 0; |
1205 | int i; | 1331 | int i; |
1206 | DPRINTF("sysctl(%p, 0x%x, %p, %p, %p, 0x%lx)\n", | 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 | i = 0; | 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 | return ret; | 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,7 +1361,8 @@ long do_getattrlist(void * arg1, void * arg2, void * arg3, uint32_t arg4, uint32 | ||
1235 | long ret; | 1361 | long ret; |
1236 | 1362 | ||
1237 | #if defined(TARGET_I386) ^ defined(__i386__) || defined(TARGET_PPC) ^ defined(__ppc__) | 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 | #endif | 1366 | #endif |
1240 | /* XXX: don't let the %s stay in there */ | 1367 | /* XXX: don't let the %s stay in there */ |
1241 | DPRINTF("getattrlist(%s, %p, %p, 0x%x, 0x%x)\n", | 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,6 +1395,91 @@ long do_getdirentriesattr(uint32_t arg1, void * arg2, void * arg3, size_t arg4, | ||
1268 | (unsigned long *)arg7, arg8)); | 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 | long no_syscall(void *cpu_env, int num) | 1484 | long no_syscall(void *cpu_env, int num) |
1273 | { | 1485 | { |
darwin-user/syscalls.h
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | ENTRY("syscall", SYS_syscall, do_unix_syscall_indirect, 0, CALL_INDIRECT, VOID) /* 0 indirect syscall */ | 3 | ENTRY("syscall", SYS_syscall, do_unix_syscall_indirect, 0, CALL_INDIRECT, VOID) /* 0 indirect syscall */ |
4 | ENTRY("exit", SYS_exit, do_exit, 1, CALL_DIRECT, INT) /* 1 */ | 4 | ENTRY("exit", SYS_exit, do_exit, 1, CALL_DIRECT, INT) /* 1 */ |
5 | ENTRY("fork", SYS_fork, fork, 0, CALL_NOERRNO, VOID) /* 2 */ | 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 | ENTRY("write", SYS_write, write, 3, CALL_DIRECT, INT, PTR, SIZE) /* 4 */ | 7 | ENTRY("write", SYS_write, write, 3, CALL_DIRECT, INT, PTR, SIZE) /* 4 */ |
8 | ENTRY("open", SYS_open, do_open, 3, CALL_DIRECT, PTR, INT, INT) /* 5 */ | 8 | ENTRY("open", SYS_open, do_open, 3, CALL_DIRECT, PTR, INT, INT) /* 5 */ |
9 | ENTRY("close", SYS_close, close, 1, CALL_DIRECT, INT) /* 6 */ | 9 | ENTRY("close", SYS_close, close, 1, CALL_DIRECT, INT) /* 6 */ |
@@ -92,7 +92,7 @@ | @@ -92,7 +92,7 @@ | ||
92 | ENTRY("getdtablesize", SYS_getdtablesize, getdtablesize, 0, CALL_DIRECT, VOID) /* 89 */ | 92 | ENTRY("getdtablesize", SYS_getdtablesize, getdtablesize, 0, CALL_DIRECT, VOID) /* 89 */ |
93 | ENTRY("dup2", SYS_dup2, dup2, 2, CALL_DIRECT, INT, INT) /* 90 */ | 93 | ENTRY("dup2", SYS_dup2, dup2, 2, CALL_DIRECT, INT, INT) /* 90 */ |
94 | ENTRY("", 91, no_syscall, 0, CALL_INDIRECT, VOID) /* 91 old getdopt */ | 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 | ENTRY("select", SYS_select, select, 5, CALL_DIRECT, INT, PTR, PTR, PTR, PTR) /* 93 */ | 96 | ENTRY("select", SYS_select, select, 5, CALL_DIRECT, INT, PTR, PTR, PTR, PTR) /* 93 */ |
97 | ENTRY("", 94, no_syscall, 0, CALL_INDIRECT, VOID) /* 94 old setdopt */ | 97 | ENTRY("", 94, no_syscall, 0, CALL_INDIRECT, VOID) /* 94 old setdopt */ |
98 | ENTRY("fsync", SYS_fsync, fsync, 1, CALL_DIRECT, INT) /* 95 */ | 98 | ENTRY("fsync", SYS_fsync, fsync, 1, CALL_DIRECT, INT) /* 95 */ |