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 uint64_t st_dev; |
412 unsigned long st_ino; | 413 uint64_t st_ino; |
413 unsigned long st_nlink; | 414 uint64_t 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 uint64_t st_rdev; |
419 long st_size; | 420 int64_t st_size; |
420 long st_blksize; | 421 int64_t st_blksize; |
421 long st_blocks; | 422 int64_t st_blocks; |
422 unsigned long st_atime_; | 423 uint64_t st_atime_; |
423 unsigned long st_atime_nsec_; | 424 uint64_t st_atime_nsec_; |
424 unsigned long st_mtime_; | 425 uint64_t st_mtime_; |
425 unsigned long st_mtime_nsec_; | 426 uint64_t st_mtime_nsec_; |
426 unsigned long st_ctime_; | 427 uint64_t st_ctime_; |
427 unsigned long st_ctime_nsec_; | 428 uint64_t st_ctime_nsec_; |
428 long __unused[3]; | 429 int64_t __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__) |
526 struct kernel_statfs { | 527 struct kernel_statfs { |
527 /* x86_64 actually defines all these fields as signed, whereas all other */ | 528 /* 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 /* platforms define them as unsigned. Leaving them at unsigned should not */ |
529 /* cause any problems. */ | 530 /* cause any problems. Make sure these are 64-bit even on x32. */ |
531 uint64_t f_type; | |
532 uint64_t f_bsize; | |
533 uint64_t f_blocks; | |
534 uint64_t f_bfree; | |
535 uint64_t f_bavail; | |
536 uint64_t f_files; | |
537 uint64_t f_ffree; | |
538 struct { int val[2]; } f_fsid; | |
539 uint64_t f_namelen; | |
540 uint64_t f_frsize; | |
541 uint64_t f_spare[5]; | |
542 }; | |
543 #else | |
544 struct kernel_statfs { | |
530 unsigned long f_type; | 545 unsigned long f_type; |
531 unsigned long f_bsize; | 546 unsigned long f_bsize; |
532 unsigned long f_blocks; | 547 unsigned long f_blocks; |
533 unsigned long f_bfree; | 548 unsigned long f_bfree; |
534 unsigned long f_bavail; | 549 unsigned long f_bavail; |
535 unsigned long f_files; | 550 unsigned long f_files; |
536 unsigned long f_ffree; | 551 unsigned long f_ffree; |
537 struct { int val[2]; } f_fsid; | 552 struct { int val[2]; } f_fsid; |
538 unsigned long f_namelen; | 553 unsigned long f_namelen; |
539 unsigned long f_frsize; | 554 unsigned long f_frsize; |
(...skipping 1243 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 #undef LSS_SYSCALL_ARG | |
1816 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) | |
1817 #undef _LSS_RETURN | |
1818 #define _LSS_RETURN(type, res, cast) \ | |
1819 do { \ | |
1820 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ | |
1821 LSS_ERRNO = -(res); \ | |
1822 res = -1; \ | |
1823 } \ | |
1824 return (type)(cast)(res); \ | |
1825 } while (0) | |
1826 #undef LSS_RETURN | |
1827 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) | |
1828 | |
1829 #undef _LSS_BODY | |
1830 #define _LSS_BODY(nr, type, name, cast, ...) \ | |
1831 long long __res; \ | |
1832 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ | |
1833 : "=a" (__res) \ | |
1834 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ | |
1835 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \ | |
1836 _LSS_RETURN(type, __res, cast) | |
1793 #undef LSS_BODY | 1837 #undef LSS_BODY |
1794 #define LSS_BODY(type,name, ...) \ | 1838 #define LSS_BODY(nr, type, name, args...) \ |
1795 long __res; \ | 1839 _LSS_BODY(nr, type, name, uintptr_t, ## args) |
1796 __asm__ __volatile__(LSS_ENTRYPOINT \ | 1840 |
1797 : "=a" (__res) : "0" (__NR_##name), \ | 1841 #undef LSS_BODY_ASM0 |
1798 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ | 1842 #undef LSS_BODY_ASM1 |
1799 LSS_RETURN(type, __res) | 1843 #undef LSS_BODY_ASM2 |
1844 #undef LSS_BODY_ASM3 | |
1845 #undef LSS_BODY_ASM4 | |
1846 #undef LSS_BODY_ASM5 | |
1847 #undef LSS_BODY_ASM6 | |
1848 #define LSS_BODY_ASM0 | |
1849 #define LSS_BODY_ASM1 LSS_BODY_ASM0 | |
1850 #define LSS_BODY_ASM2 LSS_BODY_ASM1 | |
1851 #define LSS_BODY_ASM3 LSS_BODY_ASM2 | |
1852 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" | |
1853 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" | |
1854 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" | |
1855 | |
1856 #undef LSS_BODY_CLOBBER0 | |
1857 #undef LSS_BODY_CLOBBER1 | |
1858 #undef LSS_BODY_CLOBBER2 | |
1859 #undef LSS_BODY_CLOBBER3 | |
1860 #undef LSS_BODY_CLOBBER4 | |
1861 #undef LSS_BODY_CLOBBER5 | |
1862 #undef LSS_BODY_CLOBBER6 | |
1863 #define LSS_BODY_CLOBBER0 | |
1864 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0 | |
1865 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1 | |
1866 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2 | |
1867 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10", | |
1868 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8", | |
1869 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9", | |
1870 | |
1871 #undef LSS_BODY_ARG0 | |
1872 #undef LSS_BODY_ARG1 | |
1873 #undef LSS_BODY_ARG2 | |
1874 #undef LSS_BODY_ARG3 | |
1875 #undef LSS_BODY_ARG4 | |
1876 #undef LSS_BODY_ARG5 | |
1877 #undef LSS_BODY_ARG6 | |
1878 #define LSS_BODY_ARG0() | |
1879 #define LSS_BODY_ARG1(arg1) \ | |
1880 LSS_BODY_ARG0(), "D" (arg1) | |
1881 #define LSS_BODY_ARG2(arg1, arg2) \ | |
1882 LSS_BODY_ARG1(arg1), "S" (arg2) | |
1883 #define LSS_BODY_ARG3(arg1, arg2, arg3) \ | |
1884 LSS_BODY_ARG2(arg1, arg2), "d" (arg3) | |
1885 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ | |
1886 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) | |
1887 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ | |
1888 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) | |
1889 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ | |
1890 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) | |
1891 | |
1800 #undef _syscall0 | 1892 #undef _syscall0 |
1801 #define _syscall0(type,name) \ | 1893 #define _syscall0(type,name) \ |
1802 type LSS_NAME(name)(void) { \ | 1894 type LSS_NAME(name)(void) { \ |
1803 LSS_BODY(type, name); \ | 1895 LSS_BODY(0, type, name); \ |
1804 } | 1896 } |
1805 #undef _syscall1 | 1897 #undef _syscall1 |
1806 #define _syscall1(type,name,type1,arg1) \ | 1898 #define _syscall1(type,name,type1,arg1) \ |
1807 type LSS_NAME(name)(type1 arg1) { \ | 1899 type LSS_NAME(name)(type1 arg1) { \ |
1808 LSS_BODY(type, name, "D" ((long)(arg1))); \ | 1900 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ |
1809 } | 1901 } |
1810 #undef _syscall2 | 1902 #undef _syscall2 |
1811 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | 1903 #define _syscall2(type,name,type1,arg1,type2,arg2) \ |
1812 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | 1904 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ |
1813 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ | 1905 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ |
1814 } | 1906 } |
1815 #undef _syscall3 | 1907 #undef _syscall3 |
1816 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | 1908 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ |
1817 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | 1909 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ |
1818 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ | 1910 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
1819 "d" ((long)(arg3))); \ | 1911 LSS_SYSCALL_ARG(arg3)); \ |
1820 } | 1912 } |
1821 #undef _syscall4 | 1913 #undef _syscall4 |
1822 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | 1914 #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) { \ | 1915 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ |
1824 long __res; \ | 1916 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
1825 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ | 1917 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 } | 1918 } |
1831 #undef _syscall5 | 1919 #undef _syscall5 |
1832 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1920 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1833 type5,arg5) \ | 1921 type5,arg5) \ |
1834 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1922 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1835 type5 arg5) { \ | 1923 type5 arg5) { \ |
1836 long __res; \ | 1924 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ |
1837 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ | 1925 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ |
1838 "=a" (__res) : "0" (__NR_##name), \ | 1926 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 } | 1927 } |
1844 #undef _syscall6 | 1928 #undef _syscall6 |
1845 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1929 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1846 type5,arg5,type6,arg6) \ | 1930 type5,arg5,type6,arg6) \ |
1847 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1931 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1848 type5 arg5, type6 arg6) { \ | 1932 type5 arg5, type6 arg6) { \ |
1849 long __res; \ | 1933 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;" \ | 1934 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ |
1851 LSS_ENTRYPOINT : \ | 1935 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 } | 1936 } |
1858 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | 1937 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, |
1859 int flags, void *arg, int *parent_tidptr, | 1938 int flags, void *arg, int *parent_tidptr, |
1860 void *newtls, int *child_tidptr) { | 1939 void *newtls, int *child_tidptr) { |
1861 long __res; | 1940 long long __res; |
1862 { | 1941 { |
1863 __asm__ __volatile__(/* if (fn == NULL) | 1942 __asm__ __volatile__(/* if (fn == NULL) |
1864 * return -EINVAL; | 1943 * return -EINVAL; |
1865 */ | 1944 */ |
1866 "testq %4,%4\n" | 1945 "testq %4,%4\n" |
1867 "jz 1f\n" | 1946 "jz 1f\n" |
1868 | 1947 |
1869 /* if (child_stack == NULL) | 1948 /* if (child_stack == NULL) |
1870 * return -EINVAL; | 1949 * return -EINVAL; |
1871 */ | 1950 */ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1914 */ | 1993 */ |
1915 "movq %%rax,%%rdi\n" | 1994 "movq %%rax,%%rdi\n" |
1916 "movq %3,%%rax\n" | 1995 "movq %3,%%rax\n" |
1917 LSS_ENTRYPOINT | 1996 LSS_ENTRYPOINT |
1918 | 1997 |
1919 /* Return to parent. | 1998 /* Return to parent. |
1920 */ | 1999 */ |
1921 "1:\n" | 2000 "1:\n" |
1922 : "=a" (__res) | 2001 : "=a" (__res) |
1923 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | 2002 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), |
1924 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), | 2003 "r"(LSS_SYSCALL_ARG(fn)), |
1925 "d"(parent_tidptr), "r"(newtls), | 2004 "S"(LSS_SYSCALL_ARG(child_stack)), |
1926 "r"(child_tidptr) | 2005 "D"(LSS_SYSCALL_ARG(flags)), |
2006 "r"(LSS_SYSCALL_ARG(arg)), | |
2007 "d"(LSS_SYSCALL_ARG(parent_tidptr)), | |
2008 "r"(LSS_SYSCALL_ARG(newtls)), | |
2009 "r"(LSS_SYSCALL_ARG(child_tidptr)) | |
1927 : "rsp", "memory", "r8", "r10", "r11", "rcx"); | 2010 : "rsp", "memory", "r8", "r10", "r11", "rcx"); |
1928 } | 2011 } |
1929 LSS_RETURN(int, __res); | 2012 LSS_RETURN(int, __res); |
1930 } | 2013 } |
1931 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) | 2014 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) |
1932 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, | 2015 |
1933 int, advice) | 2016 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ |
2017 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len, | |
2018 int advice) { | |
2019 LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset), | |
2020 (uint64_t)(len), LSS_SYSCALL_ARG(advice)); | |
2021 } | |
1934 | 2022 |
1935 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | 2023 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { |
1936 /* On x86-64, the kernel does not know how to return from | 2024 /* 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 | 2025 * a signal handler. Instead, it relies on user space to provide a |
1938 * restorer function that calls the rt_sigreturn() system call. | 2026 * restorer function that calls the rt_sigreturn() system call. |
1939 * Unfortunately, we cannot just reference the glibc version of this | 2027 * Unfortunately, we cannot just reference the glibc version of this |
1940 * function, as glibc goes out of its way to make it inaccessible. | 2028 * function, as glibc goes out of its way to make it inaccessible. |
1941 */ | 2029 */ |
1942 void (*res)(void); | 2030 long long res; |
1943 __asm__ __volatile__("call 2f\n" | 2031 __asm__ __volatile__("call 2f\n" |
1944 "0:.align 16\n" | 2032 "0:.align 16\n" |
1945 "1:movq %1,%%rax\n" | 2033 "1:movq %1,%%rax\n" |
1946 LSS_ENTRYPOINT | 2034 LSS_ENTRYPOINT |
1947 "2:popq %0\n" | 2035 "2:popq %0\n" |
1948 "addq $(1b-0b),%0\n" | 2036 "addq $(1b-0b),%0\n" |
1949 : "=a" (res) | 2037 : "=a" (res) |
1950 : "i" (__NR_rt_sigreturn)); | 2038 : "i" (__NR_rt_sigreturn)); |
1951 return res; | 2039 return (void (*)())(uintptr_t)res; |
Mark Seaborn
2013/04/02 15:47:17
I noticed that this breaks the NaCl build, which u
| |
1952 } | 2040 } |
1953 #elif defined(__ARM_ARCH_3__) | 2041 #elif defined(__ARM_ARCH_3__) |
1954 /* Most definitions of _syscallX() neglect to mark "memory" as being | 2042 /* Most definitions of _syscallX() neglect to mark "memory" as being |
1955 * clobbered. This causes problems with compilers, that do a better job | 2043 * clobbered. This causes problems with compilers, that do a better job |
1956 * at optimizing across __asm__ calls. | 2044 * at optimizing across __asm__ calls. |
1957 * So, we just have to redefine all of the _syscallX() macros. | 2045 * So, we just have to redefine all of the _syscallX() macros. |
1958 */ | 2046 */ |
1959 #undef LSS_REG | 2047 #undef LSS_REG |
1960 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a | 2048 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a |
1961 #undef LSS_BODY | 2049 #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) | 2735 const char*const*,a,const char*const*, e) |
2648 LSS_INLINE _syscall1(int, _exit, int, e) | 2736 LSS_INLINE _syscall1(int, _exit, int, e) |
2649 LSS_INLINE _syscall1(int, exit_group, int, e) | 2737 LSS_INLINE _syscall1(int, exit_group, int, e) |
2650 LSS_INLINE _syscall3(int, fcntl, int, f, | 2738 LSS_INLINE _syscall3(int, fcntl, int, f, |
2651 int, c, long, a) | 2739 int, c, long, a) |
2652 LSS_INLINE _syscall0(pid_t, fork) | 2740 LSS_INLINE _syscall0(pid_t, fork) |
2653 LSS_INLINE _syscall2(int, fstat, int, f, | 2741 LSS_INLINE _syscall2(int, fstat, int, f, |
2654 struct kernel_stat*, b) | 2742 struct kernel_stat*, b) |
2655 LSS_INLINE _syscall2(int, fstatfs, int, f, | 2743 LSS_INLINE _syscall2(int, fstatfs, int, f, |
2656 struct kernel_statfs*, b) | 2744 struct kernel_statfs*, b) |
2657 LSS_INLINE _syscall2(int, ftruncate, int, f, | 2745 #if defined(__x86_64__) |
2658 off_t, l) | 2746 /* Need to make sure off_t isn't truncated to 32-bits under x32. */ |
2747 LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) { | |
2748 LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l)); | |
2749 } | |
2750 #else | |
2751 LSS_INLINE _syscall2(int, ftruncate, int, f, | |
2752 off_t, l) | |
2753 #endif | |
2659 LSS_INLINE _syscall4(int, futex, int*, a, | 2754 LSS_INLINE _syscall4(int, futex, int*, a, |
2660 int, o, int, v, | 2755 int, o, int, v, |
2661 struct kernel_timespec*, t) | 2756 struct kernel_timespec*, t) |
2662 LSS_INLINE _syscall3(int, getdents, int, f, | 2757 LSS_INLINE _syscall3(int, getdents, int, f, |
2663 struct kernel_dirent*, d, int, c) | 2758 struct kernel_dirent*, d, int, c) |
2664 LSS_INLINE _syscall3(int, getdents64, int, f, | 2759 LSS_INLINE _syscall3(int, getdents64, int, f, |
2665 struct kernel_dirent64*, d, int, c) | 2760 struct kernel_dirent64*, d, int, c) |
2666 LSS_INLINE _syscall0(gid_t, getegid) | 2761 LSS_INLINE _syscall0(gid_t, getegid) |
2667 LSS_INLINE _syscall0(uid_t, geteuid) | 2762 LSS_INLINE _syscall0(uid_t, geteuid) |
2668 LSS_INLINE _syscall0(pid_t, getpgrp) | 2763 LSS_INLINE _syscall0(pid_t, getpgrp) |
(...skipping 28 matching lines...) Expand all Loading... | |
2697 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, | 2792 LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, |
2698 char *, l, size_t, s) | 2793 char *, l, size_t, s) |
2699 LSS_INLINE _syscall3(int, ioctl, int, d, | 2794 LSS_INLINE _syscall3(int, ioctl, int, d, |
2700 int, r, void *, a) | 2795 int, r, void *, a) |
2701 LSS_INLINE _syscall2(int, ioprio_get, int, which, | 2796 LSS_INLINE _syscall2(int, ioprio_get, int, which, |
2702 int, who) | 2797 int, who) |
2703 LSS_INLINE _syscall3(int, ioprio_set, int, which, | 2798 LSS_INLINE _syscall3(int, ioprio_set, int, which, |
2704 int, who, int, ioprio) | 2799 int, who, int, ioprio) |
2705 LSS_INLINE _syscall2(int, kill, pid_t, p, | 2800 LSS_INLINE _syscall2(int, kill, pid_t, p, |
2706 int, s) | 2801 int, s) |
2707 LSS_INLINE _syscall3(off_t, lseek, int, f, | 2802 #if defined(__x86_64__) |
2708 off_t, o, int, w) | 2803 /* Need to make sure off_t isn't truncated to 32-bits under x32. */ |
2804 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) { | |
2805 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), | |
2806 LSS_SYSCALL_ARG(w)); | |
2807 } | |
2808 #else | |
2809 LSS_INLINE _syscall3(off_t, lseek, int, f, | |
2810 off_t, o, int, w) | |
2811 #endif | |
2709 LSS_INLINE _syscall2(int, munmap, void*, s, | 2812 LSS_INLINE _syscall2(int, munmap, void*, s, |
2710 size_t, l) | 2813 size_t, l) |
2711 LSS_INLINE _syscall6(long, move_pages, pid_t, p, | 2814 LSS_INLINE _syscall6(long, move_pages, pid_t, p, |
2712 unsigned long, n, void **,g, int *, d, | 2815 unsigned long, n, void **,g, int *, d, |
2713 int *, s, int, f) | 2816 int *, s, int, f) |
2714 LSS_INLINE _syscall3(int, mprotect, const void *,a, | 2817 LSS_INLINE _syscall3(int, mprotect, const void *,a, |
2715 size_t, l, int, p) | 2818 size_t, l, int, p) |
2716 LSS_INLINE _syscall5(void*, _mremap, void*, o, | 2819 LSS_INLINE _syscall5(void*, _mremap, void*, o, |
2717 size_t, os, size_t, ns, | 2820 size_t, os, size_t, ns, |
2718 unsigned long, f, void *, a) | 2821 unsigned long, f, void *, a) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2797 int, f, | 2900 int, f, |
2798 const struct kernel_sockaddr*, a, int, t) | 2901 const struct kernel_sockaddr*, a, int, t) |
2799 LSS_INLINE _syscall2(int, shutdown, int, s, | 2902 LSS_INLINE _syscall2(int, shutdown, int, s, |
2800 int, h) | 2903 int, h) |
2801 LSS_INLINE _syscall3(int, socket, int, d, | 2904 LSS_INLINE _syscall3(int, socket, int, d, |
2802 int, t, int, p) | 2905 int, t, int, p) |
2803 LSS_INLINE _syscall4(int, socketpair, int, d, | 2906 LSS_INLINE _syscall4(int, socketpair, int, d, |
2804 int, t, int, p, int*, s) | 2907 int, t, int, p, int*, s) |
2805 #endif | 2908 #endif |
2806 #if defined(__x86_64__) | 2909 #if defined(__x86_64__) |
2807 LSS_INLINE _syscall4(int, fallocate, int, fd, int, mode, | 2910 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ |
2808 loff_t, offset, loff_t, len) | 2911 LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset, |
2912 loff_t len) { | |
2913 LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode), | |
2914 (uint64_t)(offset), (uint64_t)(len)); | |
2915 } | |
2809 | 2916 |
2810 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, | 2917 LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, |
2811 gid_t *egid, | 2918 gid_t *egid, |
2812 gid_t *sgid) { | 2919 gid_t *sgid) { |
2813 return LSS_NAME(getresgid)(rgid, egid, sgid); | 2920 return LSS_NAME(getresgid)(rgid, egid, sgid); |
2814 } | 2921 } |
2815 | 2922 |
2816 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, | 2923 LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, |
2817 uid_t *euid, | 2924 uid_t *euid, |
2818 uid_t *suid) { | 2925 uid_t *suid) { |
2819 return LSS_NAME(getresuid)(ruid, euid, suid); | 2926 return LSS_NAME(getresuid)(ruid, euid, suid); |
2820 } | 2927 } |
2821 | 2928 |
2822 LSS_INLINE _syscall6(void*, mmap, void*, s, | 2929 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */ |
2823 size_t, l, int, p, | 2930 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, |
2824 int, f, int, d, | 2931 __off64_t o) { |
2825 __off64_t, o) | 2932 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), |
2933 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), | |
2934 LSS_SYSCALL_ARG(d), (uint64_t)(o)); | |
2935 } | |
2826 | 2936 |
2827 LSS_INLINE _syscall4(int, newfstatat, int, d, | 2937 LSS_INLINE _syscall4(int, newfstatat, int, d, |
2828 const char *, p, | 2938 const char *, p, |
2829 struct kernel_stat*, b, int, f) | 2939 struct kernel_stat*, b, int, f) |
2830 | 2940 |
2831 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { | 2941 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { |
2832 return LSS_NAME(setfsgid)(gid); | 2942 return LSS_NAME(setfsgid)(gid); |
2833 } | 2943 } |
2834 | 2944 |
2835 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { | 2945 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; | 3569 ? 8192 : limit.rlim_cur; |
3460 #endif | 3570 #endif |
3461 } | 3571 } |
3462 case _SC_PAGESIZE: | 3572 case _SC_PAGESIZE: |
3463 return __getpagesize(); | 3573 return __getpagesize(); |
3464 default: | 3574 default: |
3465 LSS_ERRNO = ENOSYS; | 3575 LSS_ERRNO = ENOSYS; |
3466 return -1; | 3576 return -1; |
3467 } | 3577 } |
3468 } | 3578 } |
3469 #if defined(__x86_64__) || \ | 3579 #if defined(__x86_64__) |
3470 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) | 3580 /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ |
3581 LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) { | |
3582 LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), | |
3583 LSS_SYSCALL_ARG(c), (uint64_t)(o)); | |
3584 } | |
3585 | |
3586 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c, | |
3587 loff_t o) { | |
3588 LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), | |
3589 LSS_SYSCALL_ARG(c), (uint64_t)(o)); | |
3590 } | |
3591 | |
3592 LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, unsigned c) { | |
3593 LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o), | |
3594 LSS_SYSCALL_ARG(c)); | |
3595 } | |
3596 #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64 | |
3471 LSS_INLINE _syscall4(ssize_t, pread64, int, f, | 3597 LSS_INLINE _syscall4(ssize_t, pread64, int, f, |
3472 void *, b, size_t, c, | 3598 void *, b, size_t, c, |
3473 loff_t, o) | 3599 loff_t, o) |
3474 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, | 3600 LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, |
3475 const void *, b, size_t, c, | 3601 const void *, b, size_t, c, |
3476 loff_t, o) | 3602 loff_t, o) |
3477 LSS_INLINE _syscall3(int, readahead, int, f, | 3603 LSS_INLINE _syscall3(int, readahead, int, f, |
3478 loff_t, o, unsigned, c) | 3604 loff_t, o, unsigned, c) |
3479 #else | 3605 #else |
3480 #define __NR__pread64 __NR_pread64 | 3606 #define __NR__pread64 __NR_pread64 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3537 # pragma pop_macro("fstat64") | 3663 # pragma pop_macro("fstat64") |
3538 # pragma pop_macro("lstat64") | 3664 # pragma pop_macro("lstat64") |
3539 #endif | 3665 #endif |
3540 | 3666 |
3541 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) | 3667 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) |
3542 } | 3668 } |
3543 #endif | 3669 #endif |
3544 | 3670 |
3545 #endif | 3671 #endif |
3546 #endif | 3672 #endif |
OLD | NEW |