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 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1746 "1:pop %%eax\n" | 1747 "1:pop %%eax\n" |
1747 "movl %1,%%eax\n" | 1748 "movl %1,%%eax\n" |
1748 LSS_ENTRYPOINT | 1749 LSS_ENTRYPOINT |
1749 "2:popl %0\n" | 1750 "2:popl %0\n" |
1750 "addl $(1b-0b),%0\n" | 1751 "addl $(1b-0b),%0\n" |
1751 : "=a" (res) | 1752 : "=a" (res) |
1752 : "i" (__NR_sigreturn)); | 1753 : "i" (__NR_sigreturn)); |
1753 return res; | 1754 return res; |
1754 } | 1755 } |
1755 #elif defined(__x86_64__) | 1756 #elif defined(__x86_64__) |
1757 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. | |
1758 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit | |
1759 * sign extension. We can't cast pointers directly because those are | |
1760 * 32 bits, and gcc will dump ugly warnings about casting from a pointer | |
1761 * to an integer of a different size. | |
1762 */ | |
1763 #ifdef __ILP32__ | |
1764 #define LSS_SYSCALL_IGNORE_ARG_CASTS() \ | |
1765 do { \ | |
1766 _Pragma("GCC diagnostic ignored \"-Wpointer-to-int-cast\""); \ | |
Mark Seaborn
2013/03/05 17:05:19
You also need to do "GCC diagnostic push"/"pop" ot
| |
1767 _Pragma("GCC diagnostic ignored \"-Wint-to-pointer-cast\""); \ | |
1768 } while (0) | |
1769 #define LSS_SYSCALL_ARG(a) (sizeof(a) == 8 ? \ | |
Mark Seaborn
2013/03/05 17:05:19
If you're disabling the warning, you don't need th
| |
1770 (uint64_t)(a) : \ | |
1771 (uint64_t)(uintptr_t)(a)) | |
1772 #undef LSS_RETURN | |
1773 #define LSS_RETURN(type, res) \ | |
1774 do { \ | |
1775 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ | |
1776 LSS_ERRNO = -(res); \ | |
1777 res = -1; \ | |
1778 } \ | |
1779 LSS_SYSCALL_IGNORE_ARG_CASTS(); \ | |
1780 return (type) (res); \ | |
1781 } while (0) | |
1782 #else | |
1783 #define LSS_SYSCALL_IGNORE_ARG_CASTS() | |
1784 #define LSS_SYSCALL_ARG(a) ((long)(a)) | |
1785 #endif | |
1786 | |
1756 /* There are no known problems with any of the _syscallX() macros | 1787 /* There are no known problems with any of the _syscallX() macros |
1757 * currently shipping for x86_64, but we still need to be able to define | 1788 * currently shipping for x86_64, but we still need to be able to define |
1758 * our own version so that we can override the location of the errno | 1789 * our own version so that we can override the location of the errno |
1759 * location (e.g. when using the clone() system call with the CLONE_VM | 1790 * location (e.g. when using the clone() system call with the CLONE_VM |
1760 * option). | 1791 * option). |
1761 */ | 1792 */ |
1762 #undef LSS_ENTRYPOINT | 1793 #undef LSS_ENTRYPOINT |
1763 #ifdef SYS_SYSCALL_ENTRYPOINT | 1794 #ifdef SYS_SYSCALL_ENTRYPOINT |
1764 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { | 1795 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { |
1765 void (**entrypoint)(void); | 1796 void (**entrypoint)(void); |
(...skipping 20 matching lines...) Expand all Loading... | |
1786 "call *%%rcx\n" \ | 1817 "call *%%rcx\n" \ |
1787 "jmp 10002f\n" \ | 1818 "jmp 10002f\n" \ |
1788 "10001:syscall\n" \ | 1819 "10001:syscall\n" \ |
1789 "10002:\n" | 1820 "10002:\n" |
1790 | 1821 |
1791 #else | 1822 #else |
1792 #define LSS_ENTRYPOINT "syscall\n" | 1823 #define LSS_ENTRYPOINT "syscall\n" |
1793 #endif | 1824 #endif |
1794 #undef LSS_BODY | 1825 #undef LSS_BODY |
1795 #define LSS_BODY(type,name, ...) \ | 1826 #define LSS_BODY(type,name, ...) \ |
1796 long __res; \ | 1827 long long __res; \ |
1828 LSS_SYSCALL_IGNORE_ARG_CASTS(); \ | |
1797 __asm__ __volatile__(LSS_ENTRYPOINT \ | 1829 __asm__ __volatile__(LSS_ENTRYPOINT \ |
1798 : "=a" (__res) : "0" (__NR_##name), \ | 1830 : "=a" (__res) : "0" (__NR_##name), \ |
1799 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ | 1831 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ |
1800 LSS_RETURN(type, __res) | 1832 LSS_RETURN(type, __res) |
1801 #undef _syscall0 | 1833 #undef _syscall0 |
1802 #define _syscall0(type,name) \ | 1834 #define _syscall0(type,name) \ |
1803 type LSS_NAME(name)(void) { \ | 1835 type LSS_NAME(name)(void) { \ |
1804 LSS_BODY(type, name); \ | 1836 LSS_BODY(type, name); \ |
1805 } | 1837 } |
1806 #undef _syscall1 | 1838 #undef _syscall1 |
1807 #define _syscall1(type,name,type1,arg1) \ | 1839 #define _syscall1(type,name,type1,arg1) \ |
1808 type LSS_NAME(name)(type1 arg1) { \ | 1840 type LSS_NAME(name)(type1 arg1) { \ |
1809 LSS_BODY(type, name, "D" ((long)(arg1))); \ | 1841 LSS_BODY(type, name, "D" (LSS_SYSCALL_ARG(arg1))); \ |
1810 } | 1842 } |
1811 #undef _syscall2 | 1843 #undef _syscall2 |
1812 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | 1844 #define _syscall2(type,name,type1,arg1,type2,arg2) \ |
1813 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | 1845 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ |
1814 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ | 1846 LSS_BODY(type, name, "D" (LSS_SYSCALL_ARG(arg1)), \ |
1847 "S" (LSS_SYSCALL_ARG(arg2))); \ | |
1815 } | 1848 } |
1816 #undef _syscall3 | 1849 #undef _syscall3 |
1817 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | 1850 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ |
1818 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | 1851 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ |
1819 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ | 1852 LSS_BODY(type, name, "D" (LSS_SYSCALL_ARG(arg1)), \ |
1820 "d" ((long)(arg3))); \ | 1853 "S" (LSS_SYSCALL_ARG(arg2)), \ |
1854 "d" (LSS_SYSCALL_ARG(arg3))); \ | |
1821 } | 1855 } |
1822 #undef _syscall4 | 1856 #undef _syscall4 |
1823 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | 1857 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ |
1824 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | 1858 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ |
1825 long __res; \ | 1859 long long __res; \ |
1860 LSS_SYSCALL_IGNORE_ARG_CASTS(); \ | |
1826 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ | 1861 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ |
1827 "=a" (__res) : "0" (__NR_##name), \ | 1862 "=a" (__res) : "0" (__NR_##name), \ |
1828 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1863 "D" (LSS_SYSCALL_ARG(arg1)), "S" (LSS_SYSCALL_ARG(arg2)), \ |
1829 "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ | 1864 "d" (LSS_SYSCALL_ARG(arg3)), "r" (LSS_SYSCALL_ARG(arg4)) \ |
1865 : "r10", "r11", "rcx", "memory"); \ | |
1830 LSS_RETURN(type, __res); \ | 1866 LSS_RETURN(type, __res); \ |
1831 } | 1867 } |
1832 #undef _syscall5 | 1868 #undef _syscall5 |
1833 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1869 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1834 type5,arg5) \ | 1870 type5,arg5) \ |
1835 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1871 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1836 type5 arg5) { \ | 1872 type5 arg5) { \ |
1837 long __res; \ | 1873 long long __res; \ |
1874 LSS_SYSCALL_IGNORE_ARG_CASTS(); \ | |
1838 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ | 1875 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ |
1839 "=a" (__res) : "0" (__NR_##name), \ | 1876 "=a" (__res) : "0" (__NR_##name), \ |
1840 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1877 "D" (LSS_SYSCALL_ARG(arg1)), "S" (LSS_SYSCALL_ARG(arg2)), \ |
1841 "r" ((long)(arg4)), "r" ((long)(arg5)) : \ | 1878 "d" (LSS_SYSCALL_ARG(arg3)), "r" (LSS_SYSCALL_ARG(arg4)), \ |
1842 "r8", "r10", "r11", "rcx", "memory"); \ | 1879 "r" (LSS_SYSCALL_ARG(arg5)) : "r8", "r10", "r11", "rcx", \ |
1880 "memory"); \ | |
1843 LSS_RETURN(type, __res); \ | 1881 LSS_RETURN(type, __res); \ |
1844 } | 1882 } |
1845 #undef _syscall6 | 1883 #undef _syscall6 |
1846 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1884 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1847 type5,arg5,type6,arg6) \ | 1885 type5,arg5,type6,arg6) \ |
1848 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1886 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1849 type5 arg5, type6 arg6) { \ | 1887 type5 arg5, type6 arg6) { \ |
1850 long __res; \ | 1888 long long __res; \ |
1889 LSS_SYSCALL_IGNORE_ARG_CASTS(); \ | |
1851 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ | 1890 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ |
1852 LSS_ENTRYPOINT : \ | 1891 LSS_ENTRYPOINT : \ |
1853 "=a" (__res) : "0" (__NR_##name), \ | 1892 "=a" (__res) : "0" (__NR_##name), \ |
1854 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1893 "D" (LSS_SYSCALL_ARG(arg1)), "S" (LSS_SYSCALL_ARG(arg2)), \ |
1855 "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ | 1894 "d" (LSS_SYSCALL_ARG(arg3)), "r" (LSS_SYSCALL_ARG(arg4)), \ |
1856 "r8", "r9", "r10", "r11", "rcx", "memory"); \ | 1895 "r" (LSS_SYSCALL_ARG(arg5)), "r" (LSS_SYSCALL_ARG(arg6)) \ |
1896 : "r8", "r9", "r10", "r11", "rcx", "memory"); \ | |
1857 LSS_RETURN(type, __res); \ | 1897 LSS_RETURN(type, __res); \ |
1858 } | 1898 } |
1859 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | 1899 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, |
1860 int flags, void *arg, int *parent_tidptr, | 1900 int flags, void *arg, int *parent_tidptr, |
1861 void *newtls, int *child_tidptr) { | 1901 void *newtls, int *child_tidptr) { |
1862 long __res; | 1902 long long __res; |
1863 { | 1903 { |
1904 LSS_SYSCALL_IGNORE_ARG_CASTS(); | |
1864 __asm__ __volatile__(/* if (fn == NULL) | 1905 __asm__ __volatile__(/* if (fn == NULL) |
1865 * return -EINVAL; | 1906 * return -EINVAL; |
1866 */ | 1907 */ |
1867 "testq %4,%4\n" | 1908 "testq %4,%4\n" |
1868 "jz 1f\n" | 1909 "jz 1f\n" |
1869 | 1910 |
1870 /* if (child_stack == NULL) | 1911 /* if (child_stack == NULL) |
1871 * return -EINVAL; | 1912 * return -EINVAL; |
1872 */ | 1913 */ |
1873 "testq %5,%5\n" | 1914 "testq %5,%5\n" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1915 */ | 1956 */ |
1916 "movq %%rax,%%rdi\n" | 1957 "movq %%rax,%%rdi\n" |
1917 "movq %3,%%rax\n" | 1958 "movq %3,%%rax\n" |
1918 LSS_ENTRYPOINT | 1959 LSS_ENTRYPOINT |
1919 | 1960 |
1920 /* Return to parent. | 1961 /* Return to parent. |
1921 */ | 1962 */ |
1922 "1:\n" | 1963 "1:\n" |
1923 : "=a" (__res) | 1964 : "=a" (__res) |
1924 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | 1965 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), |
1925 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), | 1966 "r"(LSS_SYSCALL_ARG(fn)), |
1926 "d"(parent_tidptr), "r"(newtls), | 1967 "S"(LSS_SYSCALL_ARG(child_stack)), |
1927 "r"(child_tidptr) | 1968 "D"(LSS_SYSCALL_ARG(flags)), |
1969 "r"(LSS_SYSCALL_ARG(arg)), | |
1970 "d"(LSS_SYSCALL_ARG(parent_tidptr)), | |
1971 "r"(LSS_SYSCALL_ARG(newtls)), | |
1972 "r"(LSS_SYSCALL_ARG(child_tidptr)) | |
1928 : "rsp", "memory", "r8", "r10", "r11", "rcx"); | 1973 : "rsp", "memory", "r8", "r10", "r11", "rcx"); |
1929 } | 1974 } |
1930 LSS_RETURN(int, __res); | 1975 LSS_RETURN(int, __res); |
1931 } | 1976 } |
1932 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) | 1977 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) |
1933 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, | 1978 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, |
1934 int, advice) | 1979 int, advice) |
1935 | 1980 |
1936 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | 1981 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { |
1937 /* On x86-64, the kernel does not know how to return from | 1982 /* On x86-64, the kernel does not know how to return from |
1938 * a signal handler. Instead, it relies on user space to provide a | 1983 * a signal handler. Instead, it relies on user space to provide a |
1939 * restorer function that calls the rt_sigreturn() system call. | 1984 * restorer function that calls the rt_sigreturn() system call. |
1940 * Unfortunately, we cannot just reference the glibc version of this | 1985 * Unfortunately, we cannot just reference the glibc version of this |
1941 * function, as glibc goes out of its way to make it inaccessible. | 1986 * function, as glibc goes out of its way to make it inaccessible. |
1942 */ | 1987 */ |
1943 void (*res)(void); | 1988 long long res; |
1944 __asm__ __volatile__("call 2f\n" | 1989 __asm__ __volatile__("call 2f\n" |
1945 "0:.align 16\n" | 1990 "0:.align 16\n" |
1946 "1:movq %1,%%rax\n" | 1991 "1:movq %1,%%rax\n" |
1947 LSS_ENTRYPOINT | 1992 LSS_ENTRYPOINT |
1948 "2:popq %0\n" | 1993 "2:popq %0\n" |
1949 "addq $(1b-0b),%0\n" | 1994 "addq $(1b-0b),%0\n" |
1950 : "=a" (res) | 1995 : "=a" (res) |
1951 : "i" (__NR_rt_sigreturn)); | 1996 : "i" (__NR_rt_sigreturn)); |
1952 return res; | 1997 return (void (*)())(uintptr_t)res; |
1953 } | 1998 } |
1954 #elif defined(__ARM_ARCH_3__) | 1999 #elif defined(__ARM_ARCH_3__) |
1955 /* Most definitions of _syscallX() neglect to mark "memory" as being | 2000 /* Most definitions of _syscallX() neglect to mark "memory" as being |
1956 * clobbered. This causes problems with compilers, that do a better job | 2001 * clobbered. This causes problems with compilers, that do a better job |
1957 * at optimizing across __asm__ calls. | 2002 * at optimizing across __asm__ calls. |
1958 * So, we just have to redefine all of the _syscallX() macros. | 2003 * So, we just have to redefine all of the _syscallX() macros. |
1959 */ | 2004 */ |
1960 #undef LSS_REG | 2005 #undef LSS_REG |
1961 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a | 2006 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a |
1962 #undef LSS_BODY | 2007 #undef LSS_BODY |
(...skipping 1575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3538 # pragma pop_macro("fstat64") | 3583 # pragma pop_macro("fstat64") |
3539 # pragma pop_macro("lstat64") | 3584 # pragma pop_macro("lstat64") |
3540 #endif | 3585 #endif |
3541 | 3586 |
3542 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) | 3587 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) |
3543 } | 3588 } |
3544 #endif | 3589 #endif |
3545 | 3590 |
3546 #endif | 3591 #endif |
3547 #endif | 3592 #endif |
OLD | NEW |