Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2005-2011, Google Inc. | 1 /* Copyright (c) 2005-2011, Google Inc. |
| 2 * All rights reserved. | 2 * All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 * multiple nested 'extern "C"' blocks, just add another one here. | 96 * multiple nested 'extern "C"' blocks, just add another one here. |
| 97 */ | 97 */ |
| 98 extern "C" { | 98 extern "C" { |
| 99 #endif | 99 #endif |
| 100 | 100 |
| 101 #include <errno.h> | 101 #include <errno.h> |
| 102 #include <fcntl.h> | 102 #include <fcntl.h> |
| 103 #include <signal.h> | 103 #include <signal.h> |
| 104 #include <stdarg.h> | 104 #include <stdarg.h> |
| 105 #include <stddef.h> | 105 #include <stddef.h> |
| 106 #include <stdint.h> | |
| 106 #include <string.h> | 107 #include <string.h> |
| 107 #include <sys/ptrace.h> | 108 #include <sys/ptrace.h> |
| 108 #include <sys/resource.h> | 109 #include <sys/resource.h> |
| 109 #include <sys/time.h> | 110 #include <sys/time.h> |
| 110 #include <sys/types.h> | 111 #include <sys/types.h> |
| 111 #include <sys/syscall.h> | 112 #include <sys/syscall.h> |
| 112 #include <unistd.h> | 113 #include <unistd.h> |
| 113 #include <linux/unistd.h> | 114 #include <linux/unistd.h> |
| 114 #include <endian.h> | 115 #include <endian.h> |
| 115 | 116 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 unsigned st_atime_nsec_; | 402 unsigned st_atime_nsec_; |
| 402 unsigned st_mtime_; | 403 unsigned st_mtime_; |
| 403 unsigned st_mtime_nsec_; | 404 unsigned st_mtime_nsec_; |
| 404 unsigned st_ctime_; | 405 unsigned st_ctime_; |
| 405 unsigned st_ctime_nsec_; | 406 unsigned st_ctime_nsec_; |
| 406 unsigned __unused4; | 407 unsigned __unused4; |
| 407 unsigned __unused5; | 408 unsigned __unused5; |
| 408 }; | 409 }; |
| 409 #elif defined(__x86_64__) | 410 #elif defined(__x86_64__) |
| 410 struct kernel_stat { | 411 struct kernel_stat { |
| 411 unsigned long st_dev; | 412 unsigned long long st_dev; |
|
Mark Seaborn
2013/03/25 19:59:05
Maybe use uint64_t/int64_t in this struct for brev
vapier
2013/03/25 20:21:08
Done.
| |
| 412 unsigned long st_ino; | 413 unsigned long long st_ino; |
| 413 unsigned long st_nlink; | 414 unsigned long long st_nlink; |
| 414 unsigned st_mode; | 415 unsigned st_mode; |
| 415 unsigned st_uid; | 416 unsigned st_uid; |
| 416 unsigned st_gid; | 417 unsigned st_gid; |
| 417 unsigned __pad0; | 418 unsigned __pad0; |
| 418 unsigned long st_rdev; | 419 unsigned long long st_rdev; |
| 419 long st_size; | 420 long long st_size; |
| 420 long st_blksize; | 421 long long st_blksize; |
| 421 long st_blocks; | 422 long long st_blocks; |
| 422 unsigned long st_atime_; | 423 unsigned long long st_atime_; |
| 423 unsigned long st_atime_nsec_; | 424 unsigned long long st_atime_nsec_; |
| 424 unsigned long st_mtime_; | 425 unsigned long long st_mtime_; |
| 425 unsigned long st_mtime_nsec_; | 426 unsigned long long st_mtime_nsec_; |
| 426 unsigned long st_ctime_; | 427 unsigned long long st_ctime_; |
| 427 unsigned long st_ctime_nsec_; | 428 unsigned long long st_ctime_nsec_; |
| 428 long __unused[3]; | 429 long long __unused[3]; |
| 429 }; | 430 }; |
| 430 #elif defined(__PPC__) | 431 #elif defined(__PPC__) |
| 431 struct kernel_stat { | 432 struct kernel_stat { |
| 432 unsigned st_dev; | 433 unsigned st_dev; |
| 433 unsigned long st_ino; // ino_t | 434 unsigned long st_ino; // ino_t |
| 434 unsigned long st_mode; // mode_t | 435 unsigned long st_mode; // mode_t |
| 435 unsigned short st_nlink; // nlink_t | 436 unsigned short st_nlink; // nlink_t |
| 436 unsigned st_uid; // uid_t | 437 unsigned st_uid; // uid_t |
| 437 unsigned st_gid; // gid_t | 438 unsigned st_gid; // gid_t |
| 438 unsigned st_rdev; | 439 unsigned st_rdev; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 long f_frsize; | 516 long f_frsize; |
| 516 long f_blocks; | 517 long f_blocks; |
| 517 long f_bfree; | 518 long f_bfree; |
| 518 long f_files; | 519 long f_files; |
| 519 long f_ffree; | 520 long f_ffree; |
| 520 long f_bavail; | 521 long f_bavail; |
| 521 struct { int val[2]; } f_fsid; | 522 struct { int val[2]; } f_fsid; |
| 522 long f_namelen; | 523 long f_namelen; |
| 523 long f_spare[6]; | 524 long f_spare[6]; |
| 524 }; | 525 }; |
| 525 #else | 526 #elif !defined(__x86_64__) |
|
Mark Seaborn
2013/03/25 19:59:05
Using "!defined" to put the catch-all case first i
vapier
2013/03/25 20:21:08
Done.
| |
| 526 struct kernel_statfs { | 527 struct kernel_statfs { |
| 527 /* x86_64 actually defines all these fields as signed, whereas all other */ | |
| 528 /* platforms define them as unsigned. Leaving them at unsigned should not */ | |
| 529 /* cause any problems. */ | |
| 530 unsigned long f_type; | 528 unsigned long f_type; |
| 531 unsigned long f_bsize; | 529 unsigned long f_bsize; |
| 532 unsigned long f_blocks; | 530 unsigned long f_blocks; |
| 533 unsigned long f_bfree; | 531 unsigned long f_bfree; |
| 534 unsigned long f_bavail; | 532 unsigned long f_bavail; |
| 535 unsigned long f_files; | 533 unsigned long f_files; |
| 536 unsigned long f_ffree; | 534 unsigned long f_ffree; |
| 537 struct { int val[2]; } f_fsid; | 535 struct { int val[2]; } f_fsid; |
| 538 unsigned long f_namelen; | 536 unsigned long f_namelen; |
| 539 unsigned long f_frsize; | 537 unsigned long f_frsize; |
| 540 unsigned long f_spare[5]; | 538 unsigned long f_spare[5]; |
| 541 }; | 539 }; |
| 540 #else | |
| 541 struct kernel_statfs { | |
| 542 /* x86_64 actually defines all these fields as signed, whereas all other */ | |
| 543 /* platforms define them as unsigned. Leaving them at unsigned should not */ | |
| 544 /* cause any problems. Make sure these are 64-bit even on x32. */ | |
|
Mark Seaborn
2013/03/25 19:59:05
Nit: you're mixing single-space and double-space s
vapier
2013/03/25 20:21:08
Done.
| |
| 545 unsigned long long f_type; | |
| 546 unsigned long long f_bsize; | |
| 547 unsigned long long f_blocks; | |
| 548 unsigned long long f_bfree; | |
| 549 unsigned long long f_bavail; | |
| 550 unsigned long long f_files; | |
| 551 unsigned long long f_ffree; | |
| 552 struct { int val[2]; } f_fsid; | |
| 553 unsigned long long f_namelen; | |
| 554 unsigned long long f_frsize; | |
| 555 unsigned long long f_spare[5]; | |
| 556 }; | |
| 542 #endif | 557 #endif |
| 543 | 558 |
| 544 | 559 |
| 545 /* Definitions missing from the standard header files */ | 560 /* Definitions missing from the standard header files */ |
| 546 #ifndef O_DIRECTORY | 561 #ifndef O_DIRECTORY |
| 547 #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) | 562 #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) |
| 548 #define O_DIRECTORY 0040000 | 563 #define O_DIRECTORY 0040000 |
| 549 #else | 564 #else |
| 550 #define O_DIRECTORY 0200000 | 565 #define O_DIRECTORY 0200000 |
| 551 #endif | 566 #endif |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1783 "test %%rcx, %%rcx\n" \ | 1798 "test %%rcx, %%rcx\n" \ |
| 1784 "jz 10001f\n" \ | 1799 "jz 10001f\n" \ |
| 1785 "call *%%rcx\n" \ | 1800 "call *%%rcx\n" \ |
| 1786 "jmp 10002f\n" \ | 1801 "jmp 10002f\n" \ |
| 1787 "10001:syscall\n" \ | 1802 "10001:syscall\n" \ |
| 1788 "10002:\n" | 1803 "10002:\n" |
| 1789 | 1804 |
| 1790 #else | 1805 #else |
| 1791 #define LSS_ENTRYPOINT "syscall\n" | 1806 #define LSS_ENTRYPOINT "syscall\n" |
| 1792 #endif | 1807 #endif |
| 1808 | |
| 1809 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. | |
| 1810 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit | |
| 1811 * sign extension. We can't cast pointers directly because those are | |
| 1812 * 32 bits, and gcc will dump ugly warnings about casting from a pointer | |
| 1813 * to an integer of a different size. | |
| 1814 */ | |
| 1815 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) | |
| 1816 #define _LSS_RETURN(type, res, cast) \ | |
| 1817 do { \ | |
| 1818 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ | |
| 1819 LSS_ERRNO = -(res); \ | |
| 1820 res = -1; \ | |
| 1821 } \ | |
| 1822 return (type)(cast)(res); \ | |
| 1823 } while (0) | |
| 1824 #undef LSS_RETURN | |
| 1825 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) | |
| 1826 | |
| 1793 #undef LSS_BODY | 1827 #undef LSS_BODY |
| 1794 #define LSS_BODY(type,name, ...) \ | 1828 #define _LSS_BODY(nr, type, name, cast, ...) \ |
|
Mark Seaborn
2013/03/25 19:59:05
Maybe 'nr' -> 'arg_count', otherwise it looks like
vapier
2013/03/25 20:21:08
i used nr to match the existing mips style that ex
Mark Seaborn
2013/03/25 23:22:01
Ah, I didn't realise there is existing code that u
vapier
2013/03/26 04:01:11
Done.
| |
| 1795 long __res; \ | 1829 long long __res; \ |
| 1796 __asm__ __volatile__(LSS_ENTRYPOINT \ | 1830 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ |
| 1797 : "=a" (__res) : "0" (__NR_##name), \ | 1831 : "=a" (__res) \ |
| 1798 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ | 1832 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ |
| 1799 LSS_RETURN(type, __res) | 1833 : LSS_BODY_CLB##nr "r11", "rcx", "memory"); \ |
| 1834 _LSS_RETURN(type, __res, cast) | |
| 1835 #define LSS_BODY(nr, type, name, args...) \ | |
| 1836 _LSS_BODY(nr, type, name, uintptr_t, ## args) | |
| 1837 | |
| 1838 #define LSS_BODY_ASM0 | |
|
Mark Seaborn
2013/03/25 19:59:05
IIRC, there are some users of lss that #include li
vapier
2013/03/25 20:21:08
i'll add the #undef, but i don't see how this can
Mark Seaborn
2013/03/25 23:22:01
Have a look at third_party/tcmalloc/chromium/src/b
vapier
2013/03/26 04:01:11
sneaky
| |
| 1839 #define LSS_BODY_ASM1 LSS_BODY_ASM0 | |
| 1840 #define LSS_BODY_ASM2 LSS_BODY_ASM1 | |
| 1841 #define LSS_BODY_ASM3 LSS_BODY_ASM2 | |
| 1842 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" | |
| 1843 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" | |
| 1844 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" | |
| 1845 | |
| 1846 #define LSS_BODY_CLB0 | |
| 1847 #define LSS_BODY_CLB1 LSS_BODY_CLB0 | |
| 1848 #define LSS_BODY_CLB2 LSS_BODY_CLB1 | |
| 1849 #define LSS_BODY_CLB3 LSS_BODY_CLB2 | |
| 1850 #define LSS_BODY_CLB4 LSS_BODY_CLB3 "r10", | |
| 1851 #define LSS_BODY_CLB5 LSS_BODY_CLB4 "r8", | |
| 1852 #define LSS_BODY_CLB6 LSS_BODY_CLB5 "r9", | |
| 1853 | |
| 1854 #define LSS_BODY_ARG0() | |
| 1855 #define LSS_BODY_ARG1(arg1) \ | |
| 1856 LSS_BODY_ARG0(), "D" (arg1) | |
| 1857 #define LSS_BODY_ARG2(arg1, arg2) \ | |
| 1858 LSS_BODY_ARG1(arg1), "S" (arg2) | |
| 1859 #define LSS_BODY_ARG3(arg1, arg2, arg3) \ | |
| 1860 LSS_BODY_ARG2(arg1, arg2), "d" (arg3) | |
| 1861 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ | |
| 1862 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) | |
| 1863 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ | |
| 1864 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) | |
| 1865 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ | |
| 1866 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) | |
| 1867 | |
| 1800 #undef _syscall0 | 1868 #undef _syscall0 |
| 1801 #define _syscall0(type,name) \ | 1869 #define _syscall0(type,name) \ |
| 1802 type LSS_NAME(name)(void) { \ | 1870 type LSS_NAME(name)(void) { \ |
| 1803 LSS_BODY(type, name); \ | 1871 LSS_BODY(0, type, name); \ |
| 1804 } | 1872 } |
| 1805 #undef _syscall1 | 1873 #undef _syscall1 |
| 1806 #define _syscall1(type,name,type1,arg1) \ | 1874 #define _syscall1(type,name,type1,arg1) \ |
| 1807 type LSS_NAME(name)(type1 arg1) { \ | 1875 type LSS_NAME(name)(type1 arg1) { \ |
| 1808 LSS_BODY(type, name, "D" ((long)(arg1))); \ | 1876 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ |
| 1809 } | 1877 } |
| 1810 #undef _syscall2 | 1878 #undef _syscall2 |
| 1811 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | 1879 #define _syscall2(type,name,type1,arg1,type2,arg2) \ |
| 1812 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | 1880 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ |
| 1813 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ | 1881 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ |
| 1814 } | 1882 } |
| 1815 #undef _syscall3 | 1883 #undef _syscall3 |
| 1816 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | 1884 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ |
| 1817 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | 1885 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ |
| 1818 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ | 1886 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
| 1819 "d" ((long)(arg3))); \ | 1887 LSS_SYSCALL_ARG(arg3)); \ |
| 1820 } | 1888 } |
| 1821 #undef _syscall4 | 1889 #undef _syscall4 |
| 1822 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | 1890 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ |
| 1823 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | 1891 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ |
| 1824 long __res; \ | 1892 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
| 1825 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ | 1893 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\ |
| 1826 "=a" (__res) : "0" (__NR_##name), \ | |
| 1827 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
| 1828 "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ | |
| 1829 LSS_RETURN(type, __res); \ | |
| 1830 } | 1894 } |
| 1831 #undef _syscall5 | 1895 #undef _syscall5 |
| 1832 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1896 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
| 1833 type5,arg5) \ | 1897 type5,arg5) \ |
| 1834 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1898 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
| 1835 type5 arg5) { \ | 1899 type5 arg5) { \ |
| 1836 long __res; \ | 1900 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
| 1837 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ | 1901 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ |
| 1838 "=a" (__res) : "0" (__NR_##name), \ | 1902 LSS_SYSCALL_ARG(arg5)); \ |
| 1839 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
| 1840 "r" ((long)(arg4)), "r" ((long)(arg5)) : \ | |
| 1841 "r8", "r10", "r11", "rcx", "memory"); \ | |
| 1842 LSS_RETURN(type, __res); \ | |
| 1843 } | 1903 } |
| 1844 #undef _syscall6 | 1904 #undef _syscall6 |
| 1845 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1905 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
| 1846 type5,arg5,type6,arg6) \ | 1906 type5,arg5,type6,arg6) \ |
| 1847 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1907 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
| 1848 type5 arg5, type6 arg6) { \ | 1908 type5 arg5, type6 arg6) { \ |
| 1849 long __res; \ | 1909 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
| 1850 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ | 1910 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ |
|
Mark Seaborn
2013/03/25 19:59:05
FWIW, I find this somewhat easier to understand th
vapier
2013/03/25 20:21:08
i like the denser version myself because it's hard
| |
| 1851 LSS_ENTRYPOINT : \ | 1911 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\ |
| 1852 "=a" (__res) : "0" (__NR_##name), \ | |
| 1853 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | |
| 1854 "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ | |
| 1855 "r8", "r9", "r10", "r11", "rcx", "memory"); \ | |
| 1856 LSS_RETURN(type, __res); \ | |
| 1857 } | 1912 } |
| 1858 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | 1913 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, |
| 1859 int flags, void *arg, int *parent_tidptr, | 1914 int flags, void *arg, int *parent_tidptr, |
| 1860 void *newtls, int *child_tidptr) { | 1915 void *newtls, int *child_tidptr) { |
| 1861 long __res; | 1916 long long __res; |
| 1862 { | 1917 { |
| 1863 __asm__ __volatile__(/* if (fn == NULL) | 1918 __asm__ __volatile__(/* if (fn == NULL) |
| 1864 * return -EINVAL; | 1919 * return -EINVAL; |
| 1865 */ | 1920 */ |
| 1866 "testq %4,%4\n" | 1921 "testq %4,%4\n" |
| 1867 "jz 1f\n" | 1922 "jz 1f\n" |
| 1868 | 1923 |
| 1869 /* if (child_stack == NULL) | 1924 /* if (child_stack == NULL) |
| 1870 * return -EINVAL; | 1925 * return -EINVAL; |
| 1871 */ | 1926 */ |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1914 */ | 1969 */ |
| 1915 "movq %%rax,%%rdi\n" | 1970 "movq %%rax,%%rdi\n" |
| 1916 "movq %3,%%rax\n" | 1971 "movq %3,%%rax\n" |
| 1917 LSS_ENTRYPOINT | 1972 LSS_ENTRYPOINT |
| 1918 | 1973 |
| 1919 /* Return to parent. | 1974 /* Return to parent. |
| 1920 */ | 1975 */ |
| 1921 "1:\n" | 1976 "1:\n" |
| 1922 : "=a" (__res) | 1977 : "=a" (__res) |
| 1923 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | 1978 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), |
| 1924 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), | 1979 "r"(LSS_SYSCALL_ARG(fn)), |
| 1925 "d"(parent_tidptr), "r"(newtls), | 1980 "S"(LSS_SYSCALL_ARG(child_stack)), |
| 1926 "r"(child_tidptr) | 1981 "D"(LSS_SYSCALL_ARG(flags)), |
| 1982 "r"(LSS_SYSCALL_ARG(arg)), | |
| 1983 "d"(LSS_SYSCALL_ARG(parent_tidptr)), | |
| 1984 "r"(LSS_SYSCALL_ARG(newtls)), | |
| 1985 "r"(LSS_SYSCALL_ARG(child_tidptr)) | |
| 1927 : "rsp", "memory", "r8", "r10", "r11", "rcx"); | 1986 : "rsp", "memory", "r8", "r10", "r11", "rcx"); |
| 1928 } | 1987 } |
| 1929 LSS_RETURN(int, __res); | 1988 LSS_RETURN(int, __res); |
| 1930 } | 1989 } |
| 1931 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) | 1990 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) |
| 1932 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, | 1991 |
| 1933 int, advice) | 1992 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
|
Mark Seaborn
2013/03/25 19:59:05
'loff_t' -- see later comment
vapier
2013/03/25 20:21:08
Done.
| |
| 1993 int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len, int advice) { | |
| 1994 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset), | |
| 1995 (uint64_t)(len), LSS_SYSCALL_ARG(advice)); | |
| 1996 } | |
| 1934 | 1997 |
| 1935 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | 1998 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { |
| 1936 /* On x86-64, the kernel does not know how to return from | 1999 /* On x86-64, the kernel does not know how to return from |
| 1937 * a signal handler. Instead, it relies on user space to provide a | 2000 * a signal handler. Instead, it relies on user space to provide a |
| 1938 * restorer function that calls the rt_sigreturn() system call. | 2001 * restorer function that calls the rt_sigreturn() system call. |
| 1939 * Unfortunately, we cannot just reference the glibc version of this | 2002 * Unfortunately, we cannot just reference the glibc version of this |
| 1940 * function, as glibc goes out of its way to make it inaccessible. | 2003 * function, as glibc goes out of its way to make it inaccessible. |
| 1941 */ | 2004 */ |
| 1942 void (*res)(void); | 2005 long long res; |
| 1943 __asm__ __volatile__("call 2f\n" | 2006 __asm__ __volatile__("call 2f\n" |
| 1944 "0:.align 16\n" | 2007 "0:.align 16\n" |
| 1945 "1:movq %1,%%rax\n" | 2008 "1:movq %1,%%rax\n" |
| 1946 LSS_ENTRYPOINT | 2009 LSS_ENTRYPOINT |
| 1947 "2:popq %0\n" | 2010 "2:popq %0\n" |
| 1948 "addq $(1b-0b),%0\n" | 2011 "addq $(1b-0b),%0\n" |
| 1949 : "=a" (res) | 2012 : "=a" (res) |
| 1950 : "i" (__NR_rt_sigreturn)); | 2013 : "i" (__NR_rt_sigreturn)); |
| 1951 return res; | 2014 return (void (*)())(uintptr_t)res; |
| 1952 } | 2015 } |
| 1953 #elif defined(__ARM_ARCH_3__) | 2016 #elif defined(__ARM_ARCH_3__) |
| 1954 /* Most definitions of _syscallX() neglect to mark "memory" as being | 2017 /* Most definitions of _syscallX() neglect to mark "memory" as being |
| 1955 * clobbered. This causes problems with compilers, that do a better job | 2018 * clobbered. This causes problems with compilers, that do a better job |
| 1956 * at optimizing across __asm__ calls. | 2019 * at optimizing across __asm__ calls. |
| 1957 * So, we just have to redefine all of the _syscallX() macros. | 2020 * So, we just have to redefine all of the _syscallX() macros. |
| 1958 */ | 2021 */ |
| 1959 #undef LSS_REG | 2022 #undef LSS_REG |
| 1960 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a | 2023 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a |
| 1961 #undef LSS_BODY | 2024 #undef LSS_BODY |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2647 const char*const*,a,const char*const*, e) | 2710 const char*const*,a,const char*const*, e) |
| 2648 LSS_INLINE _syscall1(int, _exit, int, e) | 2711 LSS_INLINE _syscall1(int, _exit, int, e) |
| 2649 LSS_INLINE _syscall1(int, exit_group, int, e) | 2712 LSS_INLINE _syscall1(int, exit_group, int, e) |
| 2650 LSS_INLINE _syscall3(int, fcntl, int, f, | 2713 LSS_INLINE _syscall3(int, fcntl, int, f, |
| 2651 int, c, long, a) | 2714 int, c, long, a) |
| 2652 LSS_INLINE _syscall0(pid_t, fork) | 2715 LSS_INLINE _syscall0(pid_t, fork) |
| 2653 LSS_INLINE _syscall2(int, fstat, int, f, | 2716 LSS_INLINE _syscall2(int, fstat, int, f, |
| 2654 struct kernel_stat*, b) | 2717 struct kernel_stat*, b) |
| 2655 LSS_INLINE _syscall2(int, fstatfs, int, f, | 2718 LSS_INLINE _syscall2(int, fstatfs, int, f, |
| 2656 struct kernel_statfs*, b) | 2719 struct kernel_statfs*, b) |
| 2657 LSS_INLINE _syscall2(int, ftruncate, int, f, | 2720 #if defined(__x86_64__) |
| 2658 off_t, l) | 2721 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
| 2722 int LSS_NAME(ftruncate)(int f, off_t l) { | |
| 2723 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l)); | |
| 2724 } | |
| 2725 #else | |
| 2726 LSS_INLINE _syscall2(int, ftruncate, int, f, | |
| 2727 off_t, l) | |
| 2728 #endif | |
| 2659 LSS_INLINE _syscall4(int, futex, int*, a, | 2729 LSS_INLINE _syscall4(int, futex, int*, a, |
| 2660 int, o, int, v, | 2730 int, o, int, v, |
| 2661 struct kernel_timespec*, t) | 2731 struct kernel_timespec*, t) |
| 2662 LSS_INLINE _syscall3(int, getdents, int, f, | 2732 LSS_INLINE _syscall3(int, getdents, int, f, |
| 2663 struct kernel_dirent*, d, int, c) | 2733 struct kernel_dirent*, d, int, c) |
| 2664 LSS_INLINE _syscall3(int, getdents64, int, f, | 2734 LSS_INLINE _syscall3(int, getdents64, int, f, |
| 2665 struct kernel_dirent64*, d, int, c) | 2735 struct kernel_dirent64*, d, int, c) |
| 2666 LSS_INLINE _syscall0(gid_t, getegid) | 2736 LSS_INLINE _syscall0(gid_t, getegid) |
| 2667 LSS_INLINE _syscall0(uid_t, geteuid) | 2737 LSS_INLINE _syscall0(uid_t, geteuid) |
| 2668 LSS_INLINE _syscall0(pid_t, getpgrp) | 2738 LSS_INLINE _syscall0(pid_t, getpgrp) |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 2697 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, | 2767 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, |
| 2698 char *, l, size_t, s) | 2768 char *, l, size_t, s) |
| 2699 LSS_INLINE _syscall3(int, ioctl, int, d, | 2769 LSS_INLINE _syscall3(int, ioctl, int, d, |
| 2700 int, r, void *, a) | 2770 int, r, void *, a) |
| 2701 LSS_INLINE _syscall2(int, ioprio_get, int, which, | 2771 LSS_INLINE _syscall2(int, ioprio_get, int, which, |
| 2702 int, who) | 2772 int, who) |
| 2703 LSS_INLINE _syscall3(int, ioprio_set, int, which, | 2773 LSS_INLINE _syscall3(int, ioprio_set, int, which, |
| 2704 int, who, int, ioprio) | 2774 int, who, int, ioprio) |
| 2705 LSS_INLINE _syscall2(int, kill, pid_t, p, | 2775 LSS_INLINE _syscall2(int, kill, pid_t, p, |
| 2706 int, s) | 2776 int, s) |
| 2707 LSS_INLINE _syscall3(off_t, lseek, int, f, | 2777 #if defined(__x86_64__) |
| 2708 off_t, o, int, w) | 2778 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
| 2779 off_t LSS_NAME(lseek)(int f, off_t o, int w) { | |
| 2780 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), | |
| 2781 LSS_SYSCALL_ARG(w)); | |
| 2782 } | |
| 2783 #else | |
| 2784 LSS_INLINE _syscall3(off_t, lseek, int, f, | |
| 2785 off_t, o, int, w) | |
| 2786 #endif | |
| 2709 LSS_INLINE _syscall2(int, munmap, void*, s, | 2787 LSS_INLINE _syscall2(int, munmap, void*, s, |
| 2710 size_t, l) | 2788 size_t, l) |
| 2711 LSS_INLINE _syscall6(long, move_pages, pid_t, p, | 2789 LSS_INLINE _syscall6(long, move_pages, pid_t, p, |
| 2712 unsigned long, n, void **,g, int *, d, | 2790 unsigned long, n, void **,g, int *, d, |
| 2713 int *, s, int, f) | 2791 int *, s, int, f) |
| 2714 LSS_INLINE _syscall3(int, mprotect, const void *,a, | 2792 LSS_INLINE _syscall3(int, mprotect, const void *,a, |
| 2715 size_t, l, int, p) | 2793 size_t, l, int, p) |
| 2716 LSS_INLINE _syscall5(void*, _mremap, void*, o, | 2794 LSS_INLINE _syscall5(void*, _mremap, void*, o, |
| 2717 size_t, os, size_t, ns, | 2795 size_t, os, size_t, ns, |
| 2718 unsigned long, f, void *, a) | 2796 unsigned long, f, void *, a) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2797 int, f, | 2875 int, f, |
| 2798 const struct kernel_sockaddr*, a, int, t) | 2876 const struct kernel_sockaddr*, a, int, t) |
| 2799 LSS_INLINE _syscall2(int, shutdown, int, s, | 2877 LSS_INLINE _syscall2(int, shutdown, int, s, |
| 2800 int, h) | 2878 int, h) |
| 2801 LSS_INLINE _syscall3(int, socket, int, d, | 2879 LSS_INLINE _syscall3(int, socket, int, d, |
| 2802 int, t, int, p) | 2880 int, t, int, p) |
| 2803 LSS_INLINE _syscall4(int, socketpair, int, d, | 2881 LSS_INLINE _syscall4(int, socketpair, int, d, |
| 2804 int, t, int, p, int*, s) | 2882 int, t, int, p, int*, s) |
| 2805 #endif | 2883 #endif |
| 2806 #if defined(__x86_64__) | 2884 #if defined(__x86_64__) |
| 2807 LSS_INLINE _syscall4(int, fallocate, int, fd, int, mode, | 2885 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
|
Mark Seaborn
2013/03/25 19:59:05
'loff_t'
vapier
2013/03/25 20:21:08
Done.
| |
| 2808 loff_t, offset, loff_t, len) | 2886 int LSS_NAME(fallocate)(int f, int mode, loff_t offset, loff_t len) { |
| 2887 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode), | |
| 2888 (uint64_t)(offset), (uint64_t)(len)); | |
| 2889 } | |
| 2809 | 2890 |
| 2810 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, | 2891 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, |
| 2811 gid_t *egid, | 2892 gid_t *egid, |
| 2812 gid_t *sgid) { | 2893 gid_t *sgid) { |
| 2813 return LSS_NAME(getresgid)(rgid, egid, sgid); | 2894 return LSS_NAME(getresgid)(rgid, egid, sgid); |
| 2814 } | 2895 } |
| 2815 | 2896 |
| 2816 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, | 2897 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, |
| 2817 uid_t *euid, | 2898 uid_t *euid, |
| 2818 uid_t *suid) { | 2899 uid_t *suid) { |
| 2819 return LSS_NAME(getresuid)(ruid, euid, suid); | 2900 return LSS_NAME(getresuid)(ruid, euid, suid); |
| 2820 } | 2901 } |
| 2821 | 2902 |
| 2822 LSS_INLINE _syscall6(void*, mmap, void*, s, | 2903 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
| 2823 size_t, l, int, p, | 2904 void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, __off64_t o) { |
| 2824 int, f, int, d, | 2905 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), |
| 2825 __off64_t, o) | 2906 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), |
| 2907 LSS_SYSCALL_ARG(d), (uint64_t)(o)); | |
| 2908 } | |
| 2826 | 2909 |
| 2827 LSS_INLINE _syscall4(int, newfstatat, int, d, | 2910 LSS_INLINE _syscall4(int, newfstatat, int, d, |
| 2828 const char *, p, | 2911 const char *, p, |
| 2829 struct kernel_stat*, b, int, f) | 2912 struct kernel_stat*, b, int, f) |
| 2830 | 2913 |
| 2831 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { | 2914 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { |
| 2832 return LSS_NAME(setfsgid)(gid); | 2915 return LSS_NAME(setfsgid)(gid); |
| 2833 } | 2916 } |
| 2834 | 2917 |
| 2835 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { | 2918 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3459 ? 8192 : limit.rlim_cur; | 3542 ? 8192 : limit.rlim_cur; |
| 3460 #endif | 3543 #endif |
| 3461 } | 3544 } |
| 3462 case _SC_PAGESIZE: | 3545 case _SC_PAGESIZE: |
| 3463 return __getpagesize(); | 3546 return __getpagesize(); |
| 3464 default: | 3547 default: |
| 3465 LSS_ERRNO = ENOSYS; | 3548 LSS_ERRNO = ENOSYS; |
| 3466 return -1; | 3549 return -1; |
| 3467 } | 3550 } |
| 3468 } | 3551 } |
| 3469 #if defined(__x86_64__) || \ | 3552 #if defined(__x86_64__) |
| 3470 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) | 3553 /* Need to make sure off_t is passed as 64-bits even under x32. */ |
|
Mark Seaborn
2013/03/25 19:59:05
You mean loff_t here, since that's what these sysc
vapier
2013/03/25 20:21:08
Done.
| |
| 3554 ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) { | |
| 3555 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), | |
| 3556 LSS_SYSCALL_ARG(c), (uint64_t)(o)); | |
| 3557 } | |
| 3558 | |
| 3559 ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c, loff_t o) { | |
| 3560 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), | |
| 3561 LSS_SYSCALL_ARG(c), (uint64_t)(o)); | |
| 3562 } | |
| 3563 | |
| 3564 int LSS_NAME(readahead)(int f, loff_t o, unsigned c) { | |
| 3565 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o), | |
| 3566 LSS_SYSCALL_ARG(c)); | |
| 3567 } | |
| 3568 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64 | |
| 3471 LSS_INLINE _syscall4(ssize_t, pread64, int, f, | 3569 LSS_INLINE _syscall4(ssize_t, pread64, int, f, |
| 3472 void *, b, size_t, c, | 3570 void *, b, size_t, c, |
| 3473 loff_t, o) | 3571 loff_t, o) |
| 3474 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, | 3572 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, |
| 3475 const void *, b, size_t, c, | 3573 const void *, b, size_t, c, |
| 3476 loff_t, o) | 3574 loff_t, o) |
| 3477 LSS_INLINE _syscall3(int, readahead, int, f, | 3575 LSS_INLINE _syscall3(int, readahead, int, f, |
| 3478 loff_t, o, unsigned, c) | 3576 loff_t, o, unsigned, c) |
| 3479 #else | 3577 #else |
| 3480 #define __NR__pread64 __NR_pread64 | 3578 #define __NR__pread64 __NR_pread64 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3537 # pragma pop_macro("fstat64") | 3635 # pragma pop_macro("fstat64") |
| 3538 # pragma pop_macro("lstat64") | 3636 # pragma pop_macro("lstat64") |
| 3539 #endif | 3637 #endif |
| 3540 | 3638 |
| 3541 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) | 3639 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) |
| 3542 } | 3640 } |
| 3543 #endif | 3641 #endif |
| 3544 | 3642 |
| 3545 #endif | 3643 #endif |
| 3546 #endif | 3644 #endif |
| OLD | NEW |