Revision 263466f5 darwin-user/syscall.c

b/darwin-user/syscall.c
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 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 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 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 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 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 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 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 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 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
{

Also available in: Unified diff