From bacd43d0fb5ea0c88ed9d7d2de2c4250b987f885 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Thu, 18 Feb 2010 07:42:55 -0800 Subject: x86_64: unify sysdep.h Signed-off-by: Austin Foxley --- libc/sysdeps/linux/x86_64/sysdep.h | 352 +++++++++++++++++++++ .../nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h | 259 --------------- libpthread/nptl/sysdeps/x86_64/sysdep.h | 114 ------- 3 files changed, 352 insertions(+), 373 deletions(-) create mode 100644 libc/sysdeps/linux/x86_64/sysdep.h delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h delete mode 100644 libpthread/nptl/sysdeps/x86_64/sysdep.h diff --git a/libc/sysdeps/linux/x86_64/sysdep.h b/libc/sysdeps/linux/x86_64/sysdep.h new file mode 100644 index 000000000..2bd644f62 --- /dev/null +++ b/libc/sysdeps/linux/x86_64/sysdep.h @@ -0,0 +1,352 @@ +/* Copyright (C) 2001-2005, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _LINUX_X86_64_SYSDEP_H +#define _LINUX_X86_64_SYSDEP_H 1 + +/* There is some commonality. */ +#include +#include + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1< /* Defines RTLD_PRIVATE_ERRNO. */ +#endif + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +/* This is a kludge to make syscalls.list find these under the names + pread and pwrite, since some kernel headers define those names + and some define the *64 names for the same system calls. */ +#if !defined __NR_pread && defined __NR_pread64 +# define __NR_pread __NR_pread64 +#endif +#if !defined __NR_pwrite && defined __NR_pwrite64 +# define __NR_pwrite __NR_pwrite64 +#endif + +/* This is to help the old kernel headers where __NR_semtimedop is not + available. */ +#ifndef __NR_semtimedop +# define __NR_semtimedop 220 +#endif + + +#ifdef __ASSEMBLER__ + +/* Linux uses a negative return value to indicate syscall errors, + unlike most Unices, which use the condition codes' carry flag. + + Since version 2.1 the return value of a system call might be + negative even if the call succeeded. E.g., the `lseek' system call + might return a large offset. Therefore we must not anymore test + for < 0, but test for a real error by making sure the value in %eax + is a real error number. Linus said he will make sure the no syscall + returns a value in -1 .. -4095 as a valid result so we can savely + test with -4095. */ + +/* We don't want the label for the error handle to be global when we define + it here. */ +# ifdef __PIC__ +# define SYSCALL_ERROR_LABEL 0f +# else +# define SYSCALL_ERROR_LABEL syscall_error +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + cmpq $-4095, %rax; \ + jae SYSCALL_ERROR_LABEL; \ + L(pseudo_end): + +# undef PSEUDO_END +# define PSEUDO_END(name) \ + SYSCALL_ERROR_HANDLER \ + END (name) + +# undef PSEUDO_NOERRNO +# define PSEUDO_NOERRNO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args) + +# undef PSEUDO_END_NOERRNO +# define PSEUDO_END_NOERRNO(name) \ + END (name) + +# define ret_NOERRNO ret + +# undef PSEUDO_ERRVAL +# define PSEUDO_ERRVAL(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + negq %rax + +# undef PSEUDO_END_ERRVAL +# define PSEUDO_END_ERRVAL(name) \ + END (name) + +# define ret_ERRVAL ret + +# ifndef __PIC__ +# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +# elif defined(RTLD_PRIVATE_ERRNO) +# define SYSCALL_ERROR_HANDLER \ +0: \ + leaq rtld_errno(%rip), %rcx; \ + xorl %edx, %edx; \ + subq %rax, %rdx; \ + movl %edx, (%rcx); \ + orq $-1, %rax; \ + jmp L(pseudo_end); +# elif USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif +# define SYSCALL_ERROR_HANDLER \ +0: \ + movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\ + xorl %edx, %edx; \ + subq %rax, %rdx; \ + movl %edx, %fs:(%rcx); \ + orq $-1, %rax; \ + jmp L(pseudo_end); +# elif defined _LIBC_REENTRANT +/* Store (- %rax) into errno through the GOT. + Note that errno occupies only 4 bytes. */ +# define SYSCALL_ERROR_HANDLER \ +0: \ + xorl %edx, %edx; \ + subq %rax, %rdx; \ + pushq %rdx; \ + cfi_adjust_cfa_offset(8); \ + call __errno_location@PLT; \ + popq %rdx; \ + cfi_adjust_cfa_offset(-8); \ + movl %edx, (%rax); \ + orq $-1, %rax; \ + jmp L(pseudo_end); + +/* A quick note: it is assumed that the call to `__errno_location' does + not modify the stack! */ +# else /* Not _LIBC_REENTRANT. */ +# define SYSCALL_ERROR_HANDLER \ +0:movq errno@GOTPCREL(%RIP), %rcx; \ + xorl %edx, %edx; \ + subq %rax, %rdx; \ + movl %edx, (%rcx); \ + orq $-1, %rax; \ + jmp L(pseudo_end); +# endif /* __PIC__ */ + +/* The Linux/x86-64 kernel expects the system call parameters in + registers according to the following table: + + syscall number rax + arg 1 rdi + arg 2 rsi + arg 3 rdx + arg 4 r10 + arg 5 r8 + arg 6 r9 + + The Linux kernel uses and destroys internally these registers: + return address from + syscall rcx + eflags from syscall r11 + + Normal function call, including calls to the system call stub + functions in the libc, get the first six parameters passed in + registers and the seventh parameter and later on the stack. The + register use is as follows: + + system call number in the DO_CALL macro + arg 1 rdi + arg 2 rsi + arg 3 rdx + arg 4 rcx + arg 5 r8 + arg 6 r9 + + We have to take care that the stack is aligned to 16 bytes. When + called the stack is not aligned since the return address has just + been pushed. + + + Syscalls of more than 6 arguments are not supported. */ + +# undef DO_CALL +# define DO_CALL(syscall_name, args) \ + DOARGS_##args \ + movl $SYS_ify (syscall_name), %eax; \ + syscall; + +# define DOARGS_0 /* nothing */ +# define DOARGS_1 /* nothing */ +# define DOARGS_2 /* nothing */ +# define DOARGS_3 /* nothing */ +# define DOARGS_4 movq %rcx, %r10; +# define DOARGS_5 DOARGS_4 +# define DOARGS_6 DOARGS_5 + +#endif /* __ASSEMBLER__ */ + + +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(reg) xorq __pointer_chk_guard_local(%rip), reg; \ + rolq $17, reg +# define PTR_DEMANGLE(reg) rorq $17, reg; \ + xorq __pointer_chk_guard_local(%rip), reg +# else +# define PTR_MANGLE(reg) asm ("xorq __pointer_chk_guard_local(%%rip), %0\n" \ + "rolq $17, %0" \ + : "=r" (reg) : "0" (reg)) +# define PTR_DEMANGLE(reg) asm ("rorq $17, %0\n" \ + "xorq __pointer_chk_guard_local(%%rip), %0" \ + : "=r" (reg) : "0" (reg)) +# endif +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg; \ + rolq $17, reg +# define PTR_DEMANGLE(reg) rorq $17, reg; \ + xorq %fs:POINTER_GUARD, reg +# else +# define PTR_MANGLE(var) asm ("xorq %%fs:%c2, %0\n" \ + "rolq $17, %0" \ + : "=r" (var) \ + : "0" (var), \ + "i" (offsetof (tcbhead_t, \ + pointer_guard))) +# define PTR_DEMANGLE(var) asm ("rorq $17, %0\n" \ + "xorq %%fs:%c2, %0" \ + : "=r" (var) \ + : "0" (var), \ + "i" (offsetof (tcbhead_t, \ + pointer_guard))) +# endif +#endif + +#endif /* linux/x86_64/sysdep.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h deleted file mode 100644 index fe92a8ab5..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright (C) 2001-2005, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _LINUX_X86_64_SYSDEP_H -#define _LINUX_X86_64_SYSDEP_H 1 - -/* There is some commonality. */ -#include -#include - -#ifdef IS_IN_rtld -# include /* Defines RTLD_PRIVATE_ERRNO. */ -#endif - -/* For Linux we can use the system call table in the header file - /usr/include/asm/unistd.h - of the kernel. But these symbols do not follow the SYS_* syntax - so we have to redefine the `SYS_ify' macro here. */ -#undef SYS_ify -#define SYS_ify(syscall_name) __NR_##syscall_name - -/* This is a kludge to make syscalls.list find these under the names - pread and pwrite, since some kernel headers define those names - and some define the *64 names for the same system calls. */ -#if !defined __NR_pread && defined __NR_pread64 -# define __NR_pread __NR_pread64 -#endif -#if !defined __NR_pwrite && defined __NR_pwrite64 -# define __NR_pwrite __NR_pwrite64 -#endif - -/* This is to help the old kernel headers where __NR_semtimedop is not - available. */ -#ifndef __NR_semtimedop -# define __NR_semtimedop 220 -#endif - - -#ifdef __ASSEMBLER__ - -/* Linux uses a negative return value to indicate syscall errors, - unlike most Unices, which use the condition codes' carry flag. - - Since version 2.1 the return value of a system call might be - negative even if the call succeeded. E.g., the `lseek' system call - might return a large offset. Therefore we must not anymore test - for < 0, but test for a real error by making sure the value in %eax - is a real error number. Linus said he will make sure the no syscall - returns a value in -1 .. -4095 as a valid result so we can savely - test with -4095. */ - -/* We don't want the label for the error handle to be global when we define - it here. */ -# ifdef __PIC__ -# define SYSCALL_ERROR_LABEL 0f -# else -# define SYSCALL_ERROR_LABEL syscall_error -# endif - -# undef PSEUDO -# define PSEUDO(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args); \ - cmpq $-4095, %rax; \ - jae SYSCALL_ERROR_LABEL; \ - L(pseudo_end): - -# undef PSEUDO_END -# define PSEUDO_END(name) \ - SYSCALL_ERROR_HANDLER \ - END (name) - -# undef PSEUDO_NOERRNO -# define PSEUDO_NOERRNO(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args) - -# undef PSEUDO_END_NOERRNO -# define PSEUDO_END_NOERRNO(name) \ - END (name) - -# define ret_NOERRNO ret - -# undef PSEUDO_ERRVAL -# define PSEUDO_ERRVAL(name, syscall_name, args) \ - .text; \ - ENTRY (name) \ - DO_CALL (syscall_name, args); \ - negq %rax - -# undef PSEUDO_END_ERRVAL -# define PSEUDO_END_ERRVAL(name) \ - END (name) - -# define ret_ERRVAL ret - -# ifndef __PIC__ -# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ -# elif defined(RTLD_PRIVATE_ERRNO) -# define SYSCALL_ERROR_HANDLER \ -0: \ - leaq rtld_errno(%rip), %rcx; \ - xorl %edx, %edx; \ - subq %rax, %rdx; \ - movl %edx, (%rcx); \ - orq $-1, %rax; \ - jmp L(pseudo_end); -# elif USE___THREAD -# ifndef NOT_IN_libc -# define SYSCALL_ERROR_ERRNO __libc_errno -# else -# define SYSCALL_ERROR_ERRNO errno -# endif -# define SYSCALL_ERROR_HANDLER \ -0: \ - movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\ - xorl %edx, %edx; \ - subq %rax, %rdx; \ - movl %edx, %fs:(%rcx); \ - orq $-1, %rax; \ - jmp L(pseudo_end); -# elif defined _LIBC_REENTRANT -/* Store (- %rax) into errno through the GOT. - Note that errno occupies only 4 bytes. */ -# define SYSCALL_ERROR_HANDLER \ -0: \ - xorl %edx, %edx; \ - subq %rax, %rdx; \ - pushq %rdx; \ - cfi_adjust_cfa_offset(8); \ - call __errno_location@PLT; \ - popq %rdx; \ - cfi_adjust_cfa_offset(-8); \ - movl %edx, (%rax); \ - orq $-1, %rax; \ - jmp L(pseudo_end); - -/* A quick note: it is assumed that the call to `__errno_location' does - not modify the stack! */ -# else /* Not _LIBC_REENTRANT. */ -# define SYSCALL_ERROR_HANDLER \ -0:movq errno@GOTPCREL(%RIP), %rcx; \ - xorl %edx, %edx; \ - subq %rax, %rdx; \ - movl %edx, (%rcx); \ - orq $-1, %rax; \ - jmp L(pseudo_end); -# endif /* __PIC__ */ - -/* The Linux/x86-64 kernel expects the system call parameters in - registers according to the following table: - - syscall number rax - arg 1 rdi - arg 2 rsi - arg 3 rdx - arg 4 r10 - arg 5 r8 - arg 6 r9 - - The Linux kernel uses and destroys internally these registers: - return address from - syscall rcx - eflags from syscall r11 - - Normal function call, including calls to the system call stub - functions in the libc, get the first six parameters passed in - registers and the seventh parameter and later on the stack. The - register use is as follows: - - system call number in the DO_CALL macro - arg 1 rdi - arg 2 rsi - arg 3 rdx - arg 4 rcx - arg 5 r8 - arg 6 r9 - - We have to take care that the stack is aligned to 16 bytes. When - called the stack is not aligned since the return address has just - been pushed. - - - Syscalls of more than 6 arguments are not supported. */ - -# undef DO_CALL -# define DO_CALL(syscall_name, args) \ - DOARGS_##args \ - movl $SYS_ify (syscall_name), %eax; \ - syscall; - -# define DOARGS_0 /* nothing */ -# define DOARGS_1 /* nothing */ -# define DOARGS_2 /* nothing */ -# define DOARGS_3 /* nothing */ -# define DOARGS_4 movq %rcx, %r10; -# define DOARGS_5 DOARGS_4 -# define DOARGS_6 DOARGS_5 - -#endif /* __ASSEMBLER__ */ - - -/* Pointer mangling support. */ -#if defined NOT_IN_libc && defined IS_IN_rtld -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xorq __pointer_chk_guard_local(%rip), reg; \ - rolq $17, reg -# define PTR_DEMANGLE(reg) rorq $17, reg; \ - xorq __pointer_chk_guard_local(%rip), reg -# else -# define PTR_MANGLE(reg) asm ("xorq __pointer_chk_guard_local(%%rip), %0\n" \ - "rolq $17, %0" \ - : "=r" (reg) : "0" (reg)) -# define PTR_DEMANGLE(reg) asm ("rorq $17, %0\n" \ - "xorq __pointer_chk_guard_local(%%rip), %0" \ - : "=r" (reg) : "0" (reg)) -# endif -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg; \ - rolq $17, reg -# define PTR_DEMANGLE(reg) rorq $17, reg; \ - xorq %fs:POINTER_GUARD, reg -# else -# define PTR_MANGLE(var) asm ("xorq %%fs:%c2, %0\n" \ - "rolq $17, %0" \ - : "=r" (var) \ - : "0" (var), \ - "i" (offsetof (tcbhead_t, \ - pointer_guard))) -# define PTR_DEMANGLE(var) asm ("rorq $17, %0\n" \ - "xorq %%fs:%c2, %0" \ - : "=r" (var) \ - : "0" (var), \ - "i" (offsetof (tcbhead_t, \ - pointer_guard))) -# endif -#endif - -#endif /* linux/x86_64/sysdep.h */ diff --git a/libpthread/nptl/sysdeps/x86_64/sysdep.h b/libpthread/nptl/sysdeps/x86_64/sysdep.h deleted file mode 100644 index 350e3b5e2..000000000 --- a/libpthread/nptl/sysdeps/x86_64/sysdep.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Assembler macros for x86-64. - Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include - -#ifdef __ASSEMBLER__ - -/* Syntactic details of assembler. */ - -#ifdef HAVE_ELF - -/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ -#define ALIGNARG(log2) 1<