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 /* x32 has 32bit longs, but the syscall interface is 64bit */ | |
1758 #ifdef __ILP32__ | |
1759 #define LSS_SC_ARG(a) (sizeof(a) == 8 ? \ | |
Mark Seaborn
2013/02/28 17:46:53
"SC" is rather cryptic. Maybe "LSS_SYSCALL_ARG" i
vapier
2013/02/28 21:51:48
Done.
| |
1760 (unsigned long long)(a) : \ | |
1761 (unsigned long long)(uintptr_t)(a)) | |
Mark Seaborn
2013/02/28 17:46:53
I don't understand why you have a double cast here
vapier
2013/02/28 21:51:48
on x32, pointers are 32bit. syscall args are 64bi
Mark Seaborn
2013/03/01 23:15:40
I don't think using ?: is going to protect you fro
vapier
2013/03/01 23:21:49
sure, i didn't mean to indicate it does entirely s
Mark Seaborn
2013/03/04 16:52:44
Having extra code that only reduces the number of
| |
1762 #else | |
1763 #define LSS_SC_ARG(a) (long)(a) | |
Mark Seaborn
2013/02/28 17:46:53
Should this be "((long)(a))"?
vapier
2013/02/28 21:51:48
it could be. in practice it doesn't matter. i'll
| |
1764 #endif | |
1765 | |
1756 /* There are no known problems with any of the _syscallX() macros | 1766 /* 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 | 1767 * 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 | 1768 * 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 | 1769 * location (e.g. when using the clone() system call with the CLONE_VM |
1760 * option). | 1770 * option). |
1761 */ | 1771 */ |
1762 #undef LSS_ENTRYPOINT | 1772 #undef LSS_ENTRYPOINT |
1763 #ifdef SYS_SYSCALL_ENTRYPOINT | 1773 #ifdef SYS_SYSCALL_ENTRYPOINT |
1764 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { | 1774 static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { |
1765 void (**entrypoint)(void); | 1775 void (**entrypoint)(void); |
(...skipping 20 matching lines...) Expand all Loading... | |
1786 "call *%%rcx\n" \ | 1796 "call *%%rcx\n" \ |
1787 "jmp 10002f\n" \ | 1797 "jmp 10002f\n" \ |
1788 "10001:syscall\n" \ | 1798 "10001:syscall\n" \ |
1789 "10002:\n" | 1799 "10002:\n" |
1790 | 1800 |
1791 #else | 1801 #else |
1792 #define LSS_ENTRYPOINT "syscall\n" | 1802 #define LSS_ENTRYPOINT "syscall\n" |
1793 #endif | 1803 #endif |
1794 #undef LSS_BODY | 1804 #undef LSS_BODY |
1795 #define LSS_BODY(type,name, ...) \ | 1805 #define LSS_BODY(type,name, ...) \ |
1796 long __res; \ | 1806 long long __res; \ |
1797 __asm__ __volatile__(LSS_ENTRYPOINT \ | 1807 __asm__ __volatile__(LSS_ENTRYPOINT \ |
1798 : "=a" (__res) : "0" (__NR_##name), \ | 1808 : "=a" (__res) : "0" (__NR_##name), \ |
1799 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ | 1809 ##__VA_ARGS__ : "r11", "rcx", "memory"); \ |
1800 LSS_RETURN(type, __res) | 1810 LSS_RETURN(type, __res) |
1801 #undef _syscall0 | 1811 #undef _syscall0 |
1802 #define _syscall0(type,name) \ | 1812 #define _syscall0(type,name) \ |
1803 type LSS_NAME(name)(void) { \ | 1813 type LSS_NAME(name)(void) { \ |
1804 LSS_BODY(type, name); \ | 1814 LSS_BODY(type, name); \ |
1805 } | 1815 } |
1806 #undef _syscall1 | 1816 #undef _syscall1 |
1807 #define _syscall1(type,name,type1,arg1) \ | 1817 #define _syscall1(type,name,type1,arg1) \ |
1808 type LSS_NAME(name)(type1 arg1) { \ | 1818 type LSS_NAME(name)(type1 arg1) { \ |
1809 LSS_BODY(type, name, "D" ((long)(arg1))); \ | 1819 LSS_BODY(type, name, "D" (LSS_SC_ARG(arg1))); \ |
1810 } | 1820 } |
1811 #undef _syscall2 | 1821 #undef _syscall2 |
1812 #define _syscall2(type,name,type1,arg1,type2,arg2) \ | 1822 #define _syscall2(type,name,type1,arg1,type2,arg2) \ |
1813 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ | 1823 type LSS_NAME(name)(type1 arg1, type2 arg2) { \ |
1814 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \ | 1824 LSS_BODY(type, name, "D" (LSS_SC_ARG(arg1)), "S" (LSS_SC_ARG(arg2))); \ |
1815 } | 1825 } |
1816 #undef _syscall3 | 1826 #undef _syscall3 |
1817 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ | 1827 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ |
1818 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ | 1828 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ |
1819 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \ | 1829 LSS_BODY(type, name, "D" (LSS_SC_ARG(arg1)), "S" (LSS_SC_ARG(arg2)), \ |
1820 "d" ((long)(arg3))); \ | 1830 "d" (LSS_SC_ARG(arg3))); \ |
1821 } | 1831 } |
1822 #undef _syscall4 | 1832 #undef _syscall4 |
1823 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ | 1833 #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) { \ | 1834 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ |
1825 long __res; \ | 1835 long __res; \ |
1826 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ | 1836 __asm__ __volatile__("movq %5,%%r10;" LSS_ENTRYPOINT : \ |
1827 "=a" (__res) : "0" (__NR_##name), \ | 1837 "=a" (__res) : "0" (__NR_##name), \ |
1828 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1838 "D" (LSS_SC_ARG(arg1)), "S" (LSS_SC_ARG(arg2)), \ |
1829 "r" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \ | 1839 "d" (LSS_SC_ARG(arg3)), "r" (LSS_SC_ARG(arg4)) \ |
1840 : "r10", "r11", "rcx", "memory"); \ | |
1830 LSS_RETURN(type, __res); \ | 1841 LSS_RETURN(type, __res); \ |
1831 } | 1842 } |
1832 #undef _syscall5 | 1843 #undef _syscall5 |
1833 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1844 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1834 type5,arg5) \ | 1845 type5,arg5) \ |
1835 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1846 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1836 type5 arg5) { \ | 1847 type5 arg5) { \ |
1837 long __res; \ | 1848 long __res; \ |
1838 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ | 1849 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8;" LSS_ENTRYPOINT :\ |
1839 "=a" (__res) : "0" (__NR_##name), \ | 1850 "=a" (__res) : "0" (__NR_##name), \ |
1840 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1851 "D" (LSS_SC_ARG(arg1)), "S" (LSS_SC_ARG(arg2)), \ |
1841 "r" ((long)(arg4)), "r" ((long)(arg5)) : \ | 1852 "d" (LSS_SC_ARG(arg3)), "r" (LSS_SC_ARG(arg4)), \ |
1842 "r8", "r10", "r11", "rcx", "memory"); \ | 1853 "r" (LSS_SC_ARG(arg5)) : "r8", "r10", "r11", "rcx", "memory"); \ |
1843 LSS_RETURN(type, __res); \ | 1854 LSS_RETURN(type, __res); \ |
1844 } | 1855 } |
1845 #undef _syscall6 | 1856 #undef _syscall6 |
1846 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ | 1857 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ |
1847 type5,arg5,type6,arg6) \ | 1858 type5,arg5,type6,arg6) \ |
1848 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | 1859 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ |
1849 type5 arg5, type6 arg6) { \ | 1860 type5 arg5, type6 arg6) { \ |
1850 long __res; \ | 1861 long __res; \ |
1851 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ | 1862 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \ |
1852 LSS_ENTRYPOINT : \ | 1863 LSS_ENTRYPOINT : \ |
1853 "=a" (__res) : "0" (__NR_##name), \ | 1864 "=a" (__res) : "0" (__NR_##name), \ |
1854 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \ | 1865 "D" (LSS_SC_ARG(arg1)), "S" (LSS_SC_ARG(arg2)), \ |
1855 "r" ((long)(arg4)), "r" ((long)(arg5)), "r" ((long)(arg6)) : \ | 1866 "d" (LSS_SC_ARG(arg3)), "r" (LSS_SC_ARG(arg4)), \ |
1856 "r8", "r9", "r10", "r11", "rcx", "memory"); \ | 1867 "r" (LSS_SC_ARG(arg5)), "r" (LSS_SC_ARG(arg6)) : "r8", "r9", \ |
1868 "r10", "r11", "rcx", "memory"); \ | |
1857 LSS_RETURN(type, __res); \ | 1869 LSS_RETURN(type, __res); \ |
1858 } | 1870 } |
1859 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, | 1871 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, |
1860 int flags, void *arg, int *parent_tidptr, | 1872 int flags, void *arg, int *parent_tidptr, |
1861 void *newtls, int *child_tidptr) { | 1873 void *newtls, int *child_tidptr) { |
1862 long __res; | 1874 long __res; |
1863 { | 1875 { |
1864 __asm__ __volatile__(/* if (fn == NULL) | 1876 __asm__ __volatile__(/* if (fn == NULL) |
1865 * return -EINVAL; | 1877 * return -EINVAL; |
1866 */ | 1878 */ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1915 */ | 1927 */ |
1916 "movq %%rax,%%rdi\n" | 1928 "movq %%rax,%%rdi\n" |
1917 "movq %3,%%rax\n" | 1929 "movq %3,%%rax\n" |
1918 LSS_ENTRYPOINT | 1930 LSS_ENTRYPOINT |
1919 | 1931 |
1920 /* Return to parent. | 1932 /* Return to parent. |
1921 */ | 1933 */ |
1922 "1:\n" | 1934 "1:\n" |
1923 : "=a" (__res) | 1935 : "=a" (__res) |
1924 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), | 1936 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), |
1925 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg), | 1937 "r"(LSS_SC_ARG(fn)), "S"(LSS_SC_ARG(child_stack)) , |
Mark Seaborn
2013/02/28 17:46:53
Line is >80 characters. Please put the arguments
vapier
2013/02/28 21:51:48
Done.
| |
1926 "d"(parent_tidptr), "r"(newtls), | 1938 "D"(LSS_SC_ARG(flags)), "r"(LSS_SC_ARG(arg)), |
1927 "r"(child_tidptr) | 1939 "d"(LSS_SC_ARG(parent_tidptr)), "r"(LSS_SC_ARG(ne wtls)), |
Mark Seaborn
2013/02/28 17:46:53
Same here.
vapier
2013/02/28 21:51:48
Done.
| |
1940 "r"(LSS_SC_ARG(child_tidptr)) | |
1928 : "rsp", "memory", "r8", "r10", "r11", "rcx"); | 1941 : "rsp", "memory", "r8", "r10", "r11", "rcx"); |
1929 } | 1942 } |
1930 LSS_RETURN(int, __res); | 1943 LSS_RETURN(int, __res); |
1931 } | 1944 } |
1932 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) | 1945 LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) |
1933 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, | 1946 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len, |
1934 int, advice) | 1947 int, advice) |
1935 | 1948 |
1936 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { | 1949 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { |
1937 /* On x86-64, the kernel does not know how to return from | 1950 /* On x86-64, the kernel does not know how to return from |
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3538 # pragma pop_macro("fstat64") | 3551 # pragma pop_macro("fstat64") |
3539 # pragma pop_macro("lstat64") | 3552 # pragma pop_macro("lstat64") |
3540 #endif | 3553 #endif |
3541 | 3554 |
3542 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) | 3555 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) |
3543 } | 3556 } |
3544 #endif | 3557 #endif |
3545 | 3558 |
3546 #endif | 3559 #endif |
3547 #endif | 3560 #endif |
OLD | NEW |