Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: lss/linux_syscall_support.h

Issue 12181007: add x32 ABI support (Closed) Base URL: http://linux-syscall-support.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698