Revision 67867308 linux-user/syscall.c
b/linux-user/syscall.c | ||
---|---|---|
65 | 65 |
|
66 | 66 |
//#define DEBUG |
67 | 67 |
|
68 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) |
|
69 |
/* 16 bit uid wrappers emulation */ |
|
70 |
#define USE_UID16 |
|
71 |
#endif |
|
72 |
|
|
68 | 73 |
//#include <linux/msdos_fs.h> |
69 | 74 |
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) |
70 | 75 |
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) |
... | ... | |
1264 | 1269 |
new_env->regs[13] = newsp; |
1265 | 1270 |
new_env->regs[0] = 0; |
1266 | 1271 |
#elif defined(TARGET_SPARC) |
1267 |
printf ("HELPME: %s:%d\n", __FILE__, __LINE__); |
|
1272 |
printf ("HELPME: %s:%d\n", __FILE__, __LINE__); |
|
1273 |
#elif defined(TARGET_PPC) |
|
1274 |
if (!newsp) |
|
1275 |
newsp = env->gpr[1]; |
|
1276 |
new_env->gpr[1] = newsp; |
|
1277 |
{ |
|
1278 |
int i; |
|
1279 |
for (i = 7; i < 32; i++) |
|
1280 |
new_env->gpr[i] = 0; |
|
1281 |
} |
|
1268 | 1282 |
#else |
1269 | 1283 |
#error unsupported target CPU |
1270 | 1284 |
#endif |
... | ... | |
1325 | 1339 |
return ret; |
1326 | 1340 |
} |
1327 | 1341 |
|
1342 |
#ifdef USE_UID16 |
|
1328 | 1343 |
|
1329 |
#define high2lowuid(x) (x) |
|
1330 |
#define high2lowgid(x) (x) |
|
1331 |
#define low2highuid(x) (x) |
|
1332 |
#define low2highgid(x) (x) |
|
1344 |
static inline int high2lowuid(int uid) |
|
1345 |
{ |
|
1346 |
if (uid > 65535) |
|
1347 |
return 65534; |
|
1348 |
else |
|
1349 |
return uid; |
|
1350 |
} |
|
1351 |
|
|
1352 |
static inline int high2lowgid(int gid) |
|
1353 |
{ |
|
1354 |
if (gid > 65535) |
|
1355 |
return 65534; |
|
1356 |
else |
|
1357 |
return gid; |
|
1358 |
} |
|
1359 |
|
|
1360 |
static inline int low2highuid(int uid) |
|
1361 |
{ |
|
1362 |
if ((int16_t)uid == -1) |
|
1363 |
return -1; |
|
1364 |
else |
|
1365 |
return uid; |
|
1366 |
} |
|
1367 |
|
|
1368 |
static inline int low2highgid(int gid) |
|
1369 |
{ |
|
1370 |
if ((int16_t)gid == -1) |
|
1371 |
return -1; |
|
1372 |
else |
|
1373 |
return gid; |
|
1374 |
} |
|
1375 |
|
|
1376 |
#endif /* USE_UID16 */ |
|
1333 | 1377 |
|
1334 | 1378 |
void syscall_init(void) |
1335 | 1379 |
{ |
... | ... | |
1472 | 1516 |
case TARGET_NR_chmod: |
1473 | 1517 |
ret = get_errno(chmod((const char *)arg1, arg2)); |
1474 | 1518 |
break; |
1475 |
case TARGET_NR_lchown: |
|
1476 |
ret = get_errno(chown((const char *)arg1, arg2, arg3)); |
|
1477 |
break; |
|
1478 | 1519 |
#ifdef TARGET_NR_break |
1479 | 1520 |
case TARGET_NR_break: |
1480 | 1521 |
goto unimplemented; |
... | ... | |
1495 | 1536 |
case TARGET_NR_umount: |
1496 | 1537 |
ret = get_errno(umount((const char *)arg1)); |
1497 | 1538 |
break; |
1498 |
case TARGET_NR_setuid: |
|
1499 |
ret = get_errno(setuid(low2highuid(arg1))); |
|
1500 |
break; |
|
1501 |
case TARGET_NR_getuid: |
|
1502 |
ret = get_errno(getuid()); |
|
1503 |
break; |
|
1504 | 1539 |
case TARGET_NR_stime: |
1505 | 1540 |
{ |
1506 | 1541 |
int *time_ptr = (int *)arg1; |
... | ... | |
1596 | 1631 |
case TARGET_NR_prof: |
1597 | 1632 |
goto unimplemented; |
1598 | 1633 |
#endif |
1599 |
case TARGET_NR_setgid: |
|
1600 |
ret = get_errno(setgid(low2highgid(arg1))); |
|
1601 |
break; |
|
1602 |
case TARGET_NR_getgid: |
|
1603 |
ret = get_errno(getgid()); |
|
1604 |
break; |
|
1605 | 1634 |
case TARGET_NR_signal: |
1606 | 1635 |
goto unimplemented; |
1607 |
case TARGET_NR_geteuid: |
|
1608 |
ret = get_errno(geteuid()); |
|
1609 |
break; |
|
1610 |
case TARGET_NR_getegid: |
|
1611 |
ret = get_errno(getegid()); |
|
1612 |
break; |
|
1636 |
|
|
1613 | 1637 |
case TARGET_NR_acct: |
1614 | 1638 |
goto unimplemented; |
1615 | 1639 |
case TARGET_NR_umount2: |
... | ... | |
1844 | 1868 |
/* NOTE: ret is eax, so not transcoding must be done */ |
1845 | 1869 |
ret = do_rt_sigreturn(cpu_env); |
1846 | 1870 |
break; |
1847 |
case TARGET_NR_setreuid: |
|
1848 |
ret = get_errno(setreuid(arg1, arg2)); |
|
1849 |
break; |
|
1850 |
case TARGET_NR_setregid: |
|
1851 |
ret = get_errno(setregid(arg1, arg2)); |
|
1852 |
break; |
|
1853 | 1871 |
case TARGET_NR_sethostname: |
1854 | 1872 |
ret = get_errno(sethostname((const char *)arg1, arg2)); |
1855 | 1873 |
break; |
... | ... | |
1906 | 1924 |
ret = get_errno(settimeofday(&tv, NULL)); |
1907 | 1925 |
} |
1908 | 1926 |
break; |
1909 |
case TARGET_NR_getgroups: |
|
1910 |
{ |
|
1911 |
int gidsetsize = arg1; |
|
1912 |
uint16_t *target_grouplist = (void *)arg2; |
|
1913 |
gid_t *grouplist; |
|
1914 |
int i; |
|
1915 |
|
|
1916 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
1917 |
ret = get_errno(getgroups(gidsetsize, grouplist)); |
|
1918 |
if (!is_error(ret)) { |
|
1919 |
for(i = 0;i < gidsetsize; i++) |
|
1920 |
target_grouplist[i] = tswap16(grouplist[i]); |
|
1921 |
} |
|
1922 |
} |
|
1923 |
break; |
|
1924 |
case TARGET_NR_setgroups: |
|
1925 |
{ |
|
1926 |
int gidsetsize = arg1; |
|
1927 |
uint16_t *target_grouplist = (void *)arg2; |
|
1928 |
gid_t *grouplist; |
|
1929 |
int i; |
|
1930 |
|
|
1931 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
1932 |
for(i = 0;i < gidsetsize; i++) |
|
1933 |
grouplist[i] = tswap16(target_grouplist[i]); |
|
1934 |
ret = get_errno(setgroups(gidsetsize, grouplist)); |
|
1935 |
} |
|
1936 |
break; |
|
1937 | 1927 |
case TARGET_NR_select: |
1938 | 1928 |
{ |
1939 | 1929 |
struct target_sel_arg_struct *sel = (void *)arg1; |
... | ... | |
2026 | 2016 |
case TARGET_NR_fchmod: |
2027 | 2017 |
ret = get_errno(fchmod(arg1, arg2)); |
2028 | 2018 |
break; |
2029 |
case TARGET_NR_fchown: |
|
2030 |
ret = get_errno(fchown(arg1, arg2, arg3)); |
|
2031 |
break; |
|
2032 | 2019 |
case TARGET_NR_getpriority: |
2033 | 2020 |
ret = get_errno(getpriority(arg1, arg2)); |
2034 | 2021 |
break; |
... | ... | |
2121 | 2108 |
struct target_stat *target_st = (void *)arg2; |
2122 | 2109 |
target_st->st_dev = tswap16(st.st_dev); |
2123 | 2110 |
target_st->st_ino = tswapl(st.st_ino); |
2111 |
#if defined(TARGET_PPC) |
|
2112 |
target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */ |
|
2113 |
target_st->st_uid = tswap32(st.st_uid); |
|
2114 |
target_st->st_gid = tswap32(st.st_gid); |
|
2115 |
#else |
|
2124 | 2116 |
target_st->st_mode = tswap16(st.st_mode); |
2125 |
target_st->st_nlink = tswap16(st.st_nlink); |
|
2126 | 2117 |
target_st->st_uid = tswap16(st.st_uid); |
2127 | 2118 |
target_st->st_gid = tswap16(st.st_gid); |
2119 |
#endif |
|
2120 |
target_st->st_nlink = tswap16(st.st_nlink); |
|
2128 | 2121 |
target_st->st_rdev = tswap16(st.st_rdev); |
2129 | 2122 |
target_st->st_size = tswapl(st.st_size); |
2130 | 2123 |
target_st->st_blksize = tswapl(st.st_blksize); |
... | ... | |
2230 | 2223 |
break; |
2231 | 2224 |
case TARGET_NR_afs_syscall: |
2232 | 2225 |
goto unimplemented; |
2233 |
case TARGET_NR_setfsuid: |
|
2234 |
ret = get_errno(setfsuid(arg1)); |
|
2235 |
break; |
|
2236 |
case TARGET_NR_setfsgid: |
|
2237 |
ret = get_errno(setfsgid(arg1)); |
|
2238 |
break; |
|
2239 | 2226 |
case TARGET_NR__llseek: |
2240 | 2227 |
{ |
2241 | 2228 |
int64_t res; |
... | ... | |
2465 | 2452 |
} |
2466 | 2453 |
} |
2467 | 2454 |
break; |
2468 |
#ifdef TARGET_NR_setresuid |
|
2469 |
case TARGET_NR_setresuid: |
|
2470 |
ret = get_errno(setresuid(low2highuid(arg1), |
|
2471 |
low2highuid(arg2), |
|
2472 |
low2highuid(arg3))); |
|
2473 |
break; |
|
2474 |
#endif |
|
2475 |
#ifdef TARGET_NR_getresuid |
|
2476 |
case TARGET_NR_getresuid: |
|
2477 |
{ |
|
2478 |
int ruid, euid, suid; |
|
2479 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
|
2480 |
if (!is_error(ret)) { |
|
2481 |
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid)); |
|
2482 |
*(uint16_t *)arg2 = tswap16(high2lowuid(euid)); |
|
2483 |
*(uint16_t *)arg3 = tswap16(high2lowuid(suid)); |
|
2484 |
} |
|
2485 |
} |
|
2486 |
break; |
|
2487 |
#endif |
|
2488 |
#ifdef TARGET_NR_getresgid |
|
2489 |
case TARGET_NR_setresgid: |
|
2490 |
ret = get_errno(setresgid(low2highgid(arg1), |
|
2491 |
low2highgid(arg2), |
|
2492 |
low2highgid(arg3))); |
|
2493 |
break; |
|
2494 |
#endif |
|
2495 |
#ifdef TARGET_NR_getresgid |
|
2496 |
case TARGET_NR_getresgid: |
|
2497 |
{ |
|
2498 |
int rgid, egid, sgid; |
|
2499 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
|
2500 |
if (!is_error(ret)) { |
|
2501 |
*(uint16_t *)arg1 = high2lowgid(tswap16(rgid)); |
|
2502 |
*(uint16_t *)arg2 = high2lowgid(tswap16(egid)); |
|
2503 |
*(uint16_t *)arg3 = high2lowgid(tswap16(sgid)); |
|
2504 |
} |
|
2505 |
} |
|
2506 |
break; |
|
2507 |
#endif |
|
2508 | 2455 |
case TARGET_NR_query_module: |
2509 | 2456 |
goto unimplemented; |
2510 | 2457 |
case TARGET_NR_nfsservctl: |
2511 | 2458 |
goto unimplemented; |
2512 | 2459 |
case TARGET_NR_prctl: |
2513 | 2460 |
goto unimplemented; |
2461 |
#ifdef TARGET_NR_pread |
|
2514 | 2462 |
case TARGET_NR_pread: |
2515 | 2463 |
page_unprotect_range((void *)arg2, arg3); |
2516 | 2464 |
ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4)); |
... | ... | |
2518 | 2466 |
case TARGET_NR_pwrite: |
2519 | 2467 |
ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4)); |
2520 | 2468 |
break; |
2521 |
case TARGET_NR_chown: |
|
2522 |
ret = get_errno(chown((const char *)arg1, arg2, arg3)); |
|
2523 |
break; |
|
2469 |
#endif |
|
2524 | 2470 |
case TARGET_NR_getcwd: |
2525 | 2471 |
ret = get_errno(sys_getcwd1((char *)arg1, arg2)); |
2526 | 2472 |
break; |
... | ... | |
2594 | 2540 |
} |
2595 | 2541 |
break; |
2596 | 2542 |
|
2543 |
#ifdef USE_UID16 |
|
2544 |
case TARGET_NR_lchown: |
|
2545 |
ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2546 |
break; |
|
2547 |
case TARGET_NR_getuid: |
|
2548 |
ret = get_errno(high2lowuid(getuid())); |
|
2549 |
break; |
|
2550 |
case TARGET_NR_getgid: |
|
2551 |
ret = get_errno(high2lowgid(getgid())); |
|
2552 |
break; |
|
2553 |
case TARGET_NR_geteuid: |
|
2554 |
ret = get_errno(high2lowuid(geteuid())); |
|
2555 |
break; |
|
2556 |
case TARGET_NR_getegid: |
|
2557 |
ret = get_errno(high2lowgid(getegid())); |
|
2558 |
break; |
|
2559 |
case TARGET_NR_setreuid: |
|
2560 |
ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); |
|
2561 |
break; |
|
2562 |
case TARGET_NR_setregid: |
|
2563 |
ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2))); |
|
2564 |
break; |
|
2565 |
case TARGET_NR_getgroups: |
|
2566 |
{ |
|
2567 |
int gidsetsize = arg1; |
|
2568 |
uint16_t *target_grouplist = (void *)arg2; |
|
2569 |
gid_t *grouplist; |
|
2570 |
int i; |
|
2571 |
|
|
2572 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
2573 |
ret = get_errno(getgroups(gidsetsize, grouplist)); |
|
2574 |
if (!is_error(ret)) { |
|
2575 |
for(i = 0;i < gidsetsize; i++) |
|
2576 |
target_grouplist[i] = tswap16(grouplist[i]); |
|
2577 |
} |
|
2578 |
} |
|
2579 |
break; |
|
2580 |
case TARGET_NR_setgroups: |
|
2581 |
{ |
|
2582 |
int gidsetsize = arg1; |
|
2583 |
uint16_t *target_grouplist = (void *)arg2; |
|
2584 |
gid_t *grouplist; |
|
2585 |
int i; |
|
2586 |
|
|
2587 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
2588 |
for(i = 0;i < gidsetsize; i++) |
|
2589 |
grouplist[i] = tswap16(target_grouplist[i]); |
|
2590 |
ret = get_errno(setgroups(gidsetsize, grouplist)); |
|
2591 |
} |
|
2592 |
break; |
|
2593 |
case TARGET_NR_fchown: |
|
2594 |
ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2595 |
break; |
|
2596 |
#ifdef TARGET_NR_setresuid |
|
2597 |
case TARGET_NR_setresuid: |
|
2598 |
ret = get_errno(setresuid(low2highuid(arg1), |
|
2599 |
low2highuid(arg2), |
|
2600 |
low2highuid(arg3))); |
|
2601 |
break; |
|
2602 |
#endif |
|
2603 |
#ifdef TARGET_NR_getresuid |
|
2604 |
case TARGET_NR_getresuid: |
|
2605 |
{ |
|
2606 |
int ruid, euid, suid; |
|
2607 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
|
2608 |
if (!is_error(ret)) { |
|
2609 |
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid)); |
|
2610 |
*(uint16_t *)arg2 = tswap16(high2lowuid(euid)); |
|
2611 |
*(uint16_t *)arg3 = tswap16(high2lowuid(suid)); |
|
2612 |
} |
|
2613 |
} |
|
2614 |
break; |
|
2615 |
#endif |
|
2616 |
#ifdef TARGET_NR_getresgid |
|
2617 |
case TARGET_NR_setresgid: |
|
2618 |
ret = get_errno(setresgid(low2highgid(arg1), |
|
2619 |
low2highgid(arg2), |
|
2620 |
low2highgid(arg3))); |
|
2621 |
break; |
|
2622 |
#endif |
|
2623 |
#ifdef TARGET_NR_getresgid |
|
2624 |
case TARGET_NR_getresgid: |
|
2625 |
{ |
|
2626 |
int rgid, egid, sgid; |
|
2627 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
|
2628 |
if (!is_error(ret)) { |
|
2629 |
*(uint16_t *)arg1 = tswap16(high2lowgid(rgid)); |
|
2630 |
*(uint16_t *)arg2 = tswap16(high2lowgid(egid)); |
|
2631 |
*(uint16_t *)arg3 = tswap16(high2lowgid(sgid)); |
|
2632 |
} |
|
2633 |
} |
|
2634 |
break; |
|
2635 |
#endif |
|
2636 |
case TARGET_NR_chown: |
|
2637 |
ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2638 |
break; |
|
2639 |
case TARGET_NR_setuid: |
|
2640 |
ret = get_errno(setuid(low2highuid(arg1))); |
|
2641 |
break; |
|
2642 |
case TARGET_NR_setgid: |
|
2643 |
ret = get_errno(setgid(low2highgid(arg1))); |
|
2644 |
break; |
|
2645 |
case TARGET_NR_setfsuid: |
|
2646 |
ret = get_errno(setfsuid(arg1)); |
|
2647 |
break; |
|
2648 |
case TARGET_NR_setfsgid: |
|
2649 |
ret = get_errno(setfsgid(arg1)); |
|
2650 |
break; |
|
2651 |
#endif /* USE_UID16 */ |
|
2652 |
|
|
2597 | 2653 |
case TARGET_NR_lchown32: |
2598 | 2654 |
ret = get_errno(lchown((const char *)arg1, arg2, arg3)); |
2599 | 2655 |
break; |
... | ... | |
2665 | 2721 |
case TARGET_NR_setfsgid32: |
2666 | 2722 |
ret = get_errno(setfsgid(arg1)); |
2667 | 2723 |
break; |
2724 |
|
|
2668 | 2725 |
case TARGET_NR_pivot_root: |
2669 | 2726 |
goto unimplemented; |
2670 | 2727 |
case TARGET_NR_mincore: |
Also available in: Unified diff