diff options
Diffstat (limited to 'libc/sysdeps/unix/sysv/linux/x86_64')
53 files changed, 4569 insertions, 0 deletions
diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Implies b/libc/sysdeps/unix/sysv/linux/x86_64/Implies new file mode 100644 index 000000000..8d91c8009 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/Implies @@ -0,0 +1 @@ +unix/sysv/linux/wordsize-64 diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Makefile b/libc/sysdeps/unix/sysv/linux/x86_64/Makefile new file mode 100644 index 000000000..0f2036723 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/Makefile @@ -0,0 +1,15 @@ +32bit-predefine = __i386__ +64bit-predefine = __x86_64__ + +ifeq ($(subdir),misc) +sysdep_routines += ioperm iopl +sysdep_headers += sys/perm.h sys/reg.h sys/debugreg.h sys/io.h +endif + +ifeq ($(subdir),stdlib) +sysdep_routines += __start_context +endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/Versions b/libc/sysdeps/unix/sysv/linux/x86_64/Versions new file mode 100644 index 000000000..fd1b3cc29 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/Versions @@ -0,0 +1,9 @@ +libc { + GLIBC_2.2.5 { + arch_prctl; __arch_prctl; + + ioperm; iopl; + + modify_ldt; + } +} diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S new file mode 100644 index 000000000..37d391760 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/__start_context.S @@ -0,0 +1,49 @@ +/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2002. + + 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 <sysdep.h> + +/* This is the helper code which gets called if a function which is + registered with 'makecontext' returns. In this case we have to + install the context listed in the uc_link element of the context + 'makecontext' manipulated at the time of the 'makecontext' call. + If the pointer is NULL the process must terminate. */ + + +ENTRY(__start_context) + /* This removes the parameters passed to the function given to + 'makecontext' from the stack. RBX contains the address + on the stack pointer for the next context. */ + movq %rbx, %rsp + + popq %rdi /* This is the next context. */ + cfi_adjust_cfa_offset(-8) + testq %rdi, %rdi + je 2f /* If it is zero exit. */ + + call JUMPTARGET(__setcontext) + /* If this returns (which can happen if the syscall fails) we'll + exit the program with the return error value (-1). */ + +2: movq %rax,%rdi + call HIDDEN_JUMPTARGET(exit) + /* The 'exit' call should never return. In case it does cause + the process to terminate. */ + hlt +END(__start_context) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h new file mode 100644 index 000000000..228a8d41a --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/a.out.h @@ -0,0 +1,13 @@ +#ifndef __A_OUT_GNU_H__ +# error "Never use <bits/a.out.h> directly; include <a.out.h> instead." +#endif + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 + +/* Signal to users of this header that this architecture really doesn't + support a.out binary format. */ +#define __NO_A_OUT_SUPPORT 1 + +#endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h new file mode 100644 index 000000000..a51a564cb --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/environments.h @@ -0,0 +1,87 @@ +/* Copyright (C) 1999, 2001, 2004 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 _UNISTD_H +# error "Never include this file directly. Use <unistd.h> instead" +#endif + +#include <bits/wordsize.h> + +/* This header should define the following symbols under the described + situations. A value `1' means that the model is always supported, + `-1' means it is never supported. Undefined means it cannot be + statically decided. + + _POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type + _POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type + + _POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type + _POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type + + The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and + _XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard + and are available only for compatibility. +*/ + +#if __WORDSIZE == 64 + +/* Environments with 32-bit wide pointers are optionally provided. + Therefore following macros aren't defined: + # undef _POSIX_V6_ILP32_OFF32 + # undef _POSIX_V6_ILP32_OFFBIG + # undef _XBS5_ILP32_OFF32 + # undef _XBS5_ILP32_OFFBIG + and users need to check at runtime. */ + +/* We also have no use (for now) for an environment with bigger pointers + and offsets. */ +# define _POSIX_V6_LPBIG_OFFBIG -1 +# define _XBS5_LPBIG_OFFBIG -1 + +/* By default we have 64-bit wide `long int', pointers and `off_t'. */ +# define _POSIX_V6_LP64_OFF64 1 +# define _XBS5_LP64_OFF64 1 + +#else /* __WORDSIZE == 32 */ + +/* By default we have 32-bit wide `int', `long int', pointers and `off_t' + and all platforms support LFS. */ +# define _POSIX_V6_ILP32_OFF32 1 +# define _POSIX_V6_ILP32_OFFBIG 1 +# define _XBS5_ILP32_OFF32 1 +# define _XBS5_ILP32_OFFBIG 1 + +/* We optionally provide an environment with the above size but an 64-bit + side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */ + +/* Environments with 64-bit wide pointers can be provided, + so these macros aren't defined: + # undef _POSIX_V6_LP64_OFF64 + # undef _POSIX_V6_LPBIG_OFFBIG + # undef _XBS5_LP64_OFF64 + # undef _XBS5_LPBIG_OFFBIG + and sysconf tests for it at runtime. */ + +#endif /* __WORDSIZE == 32 */ + +#define __ILP32_OFF32_CFLAGS "-m32" +#define __ILP32_OFFBIG_CFLAGS "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" +#define __ILP32_OFF32_LDFLAGS "-m32" +#define __ILP32_OFFBIG_LDFLAGS "-m32" +#define __LP64_OFF64_CFLAGS "-m64" +#define __LP64_OFF64_LDFLAGS "-m64" diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h new file mode 100644 index 000000000..4f10f2222 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h @@ -0,0 +1,250 @@ +/* O_*, F_*, FD_* bit values for Linux/x86-64. + Copyright (C) 2001, 2002, 2004, 2006 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 _FCNTL_H +# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." +#endif + +#include <sys/types.h> +#include <bits/wordsize.h> +#ifdef __USE_GNU +# include <bits/uio.h> +#endif + + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define O_FSYNC O_SYNC +#define O_ASYNC 020000 + +#ifdef __USE_GNU +# define O_DIRECT 040000 /* Direct disk access. */ +# define O_DIRECTORY 0200000 /* Must be a directory. */ +# define O_NOFOLLOW 0400000 /* Do not follow links. */ +# define O_NOATIME 01000000 /* Do not set atime. */ +#endif + +/* For now Linux has synchronisity options for data and read operations. + We define the symbols here but let them do the same as O_SYNC since + this is a superset. */ +#if defined __USE_POSIX199309 || defined __USE_UNIX98 +# define O_DSYNC O_SYNC /* Synchronize data. */ +# define O_RSYNC O_SYNC /* Synchronize read operations. */ +#endif + +#ifdef __USE_LARGEFILE64 +# if __WORDSIZE == 64 +# define O_LARGEFILE 0 +# else +# define O_LARGEFILE 0100000 +# endif +#endif + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#if __WORDSIZE == 64 +# define F_GETLK 5 /* Get record locking info. */ +# define F_SETLK 6 /* Set record locking info (non-blocking). */ +# define F_SETLKW 7 /* Set record locking info (blocking). */ +/* Not necessary, we always have 64-bit offsets. */ +# define F_GETLK64 5 /* Get record locking info. */ +# define F_SETLK64 6 /* Set record locking info (non-blocking). */ +# define F_SETLKW64 7 /* Set record locking info (blocking). */ +#else +# ifndef __USE_FILE_OFFSET64 +# define F_GETLK 5 /* Get record locking info. */ +# define F_SETLK 6 /* Set record locking info (non-blocking). */ +# define F_SETLKW 7 /* Set record locking info (blocking). */ +# else +# define F_GETLK F_GETLK64 /* Get record locking info. */ +# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/ +# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */ +# endif +# define F_GETLK64 12 /* Get record locking info. */ +# define F_SETLK64 13 /* Set record locking info (non-blocking). */ +# define F_SETLKW64 14 /* Set record locking info (blocking). */ +#endif + +#if defined __USE_BSD || defined __USE_UNIX98 +# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */ +# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */ +#endif + +#ifdef __USE_GNU +# define F_SETSIG 10 /* Set number of signal to be sent. */ +# define F_GETSIG 11 /* Get number of signal to be sent. */ +#endif + +#ifdef __USE_GNU +# define F_SETLEASE 1024 /* Set a lease. */ +# define F_GETLEASE 1025 /* Enquire what lease is active. */ +# define F_NOTIFY 1026 /* Request notfications on a directory. */ +#endif + +/* For F_[GET|SET]FD. */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ +#define F_RDLCK 0 /* Read lock. */ +#define F_WRLCK 1 /* Write lock. */ +#define F_UNLCK 2 /* Remove lock. */ + +/* For old implementation of bsd flock(). */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +#ifdef __USE_BSD +/* Operations for bsd flock(), also used by the kernel implementation. */ +# define LOCK_SH 1 /* shared lock */ +# define LOCK_EX 2 /* exclusive lock */ +# define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +# define LOCK_UN 8 /* remove lock */ +#endif + +#ifdef __USE_GNU +# define LOCK_MAND 32 /* This is a mandatory flock: */ +# define LOCK_READ 64 /* ... which allows concurrent read operations. */ +# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */ +# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */ +#endif + +#ifdef __USE_GNU +/* Types of directory notifications that may be requested with F_NOTIFY. */ +# define DN_ACCESS 0x00000001 /* File accessed. */ +# define DN_MODIFY 0x00000002 /* File modified. */ +# define DN_CREATE 0x00000004 /* File created. */ +# define DN_DELETE 0x00000008 /* File removed. */ +# define DN_RENAME 0x00000010 /* File renamed. */ +# define DN_ATTRIB 0x00000020 /* File changed attibutes. */ +# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */ +#endif + +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ +#ifndef __USE_FILE_OFFSET64 + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ +#else + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ +#endif + __pid_t l_pid; /* Process holding the lock. */ + }; + +#ifdef __USE_LARGEFILE64 +struct flock64 + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; +#endif + +/* Define some more compatibility macros to be backward compatible with + BSD systems which did not managed to hide these kernel macros. */ +#ifdef __USE_BSD +# define FAPPEND O_APPEND +# define FFSYNC O_FSYNC +# define FASYNC O_ASYNC +# define FNONBLOCK O_NONBLOCK +# define FNDELAY O_NDELAY +#endif /* Use BSD. */ + +/* Advise to `posix_fadvise'. */ +#ifdef __USE_XOPEN2K +# define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif + + +#ifdef __USE_GNU +/* Flags for SYNC_FILE_RANGE. */ +# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages + in the range before performing the + write. */ +# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those + dirty pages in the range which are + not presently under writeback. */ +# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in + the range after performing the + write. */ + +/* Flags for SPLICE and VMSPLICE. */ +# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */ +# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing + (but we may still block on the fd + we splice from/to). */ +# define SPLICE_F_MORE 4 /* Expect more data. */ +# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */ +#endif + +__BEGIN_DECLS + +#ifdef __USE_GNU + +/* Provide kernel hint to read ahead. */ +extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) + __THROW; + + +/* Selective file content synch'ing. */ +extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to, + unsigned int __flags); + + +/* Splice address range into a pipe. */ +extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count, + unsigned int __flags); + +/* Splice two files together. */ +extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags) + __THROW; + +/* In-kernel implementation of tee for pipe buffers. */ +extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags) + __THROW; + +#endif + +__END_DECLS diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h new file mode 100644 index 000000000..535c9edcf --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/mman.h @@ -0,0 +1,104 @@ +/* Definitions for POSIX memory map interface. Linux/x86_64 version. + Copyright (C) 2001, 2003, 2005, 2006 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 _SYS_MMAN_H +# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead." +#endif + +/* The following definitions basically come from the kernel headers. + But the kernel header is not namespace clean. */ + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_READ 0x1 /* Page can be read. */ +#define PROT_WRITE 0x2 /* Page can be written. */ +#define PROT_EXEC 0x4 /* Page can be executed. */ +#define PROT_NONE 0x0 /* Page can not be accessed. */ +#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of + growsdown vma (mprotect only). */ +#define PROT_GROWSUP 0x02000000 /* Extend change to start of + growsup vma (mprotect only). */ + +/* Sharing types (must choose one and only one of these). */ +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes are private. */ +#ifdef __USE_MISC +# define MAP_TYPE 0x0f /* Mask for type of mapping. */ +#endif + +/* Other flags. */ +#define MAP_FIXED 0x10 /* Interpret addr exactly. */ +#ifdef __USE_MISC +# define MAP_FILE 0 +# define MAP_ANONYMOUS 0x20 /* Don't use a file. */ +# define MAP_ANON MAP_ANONYMOUS +# define MAP_32BIT 0x40 /* Only give out 32-bit addresses. */ +#endif + +/* These are Linux-specific. */ +#ifdef __USE_MISC +# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */ +# define MAP_DENYWRITE 0x00800 /* ETXTBSY */ +# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */ +# define MAP_LOCKED 0x02000 /* Lock the mapping. */ +# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */ +# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */ +# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ +#endif + +/* Flags to `msync'. */ +#define MS_ASYNC 1 /* Sync memory asynchronously. */ +#define MS_SYNC 4 /* Synchronous memory sync. */ +#define MS_INVALIDATE 2 /* Invalidate the caches. */ + +/* Flags for `mlockall'. */ +#define MCL_CURRENT 1 /* Lock all currently mapped pages. */ +#define MCL_FUTURE 2 /* Lock all additions to address + space. */ + +/* Flags for `mremap'. */ +#ifdef __USE_GNU +# define MREMAP_MAYMOVE 1 +# define MREMAP_FIXED 2 +#endif + +/* Advice to `madvise'. */ +#ifdef __USE_BSD +# define MADV_NORMAL 0 /* No further special treatment. */ +# define MADV_RANDOM 1 /* Expect random page references. */ +# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define MADV_WILLNEED 3 /* Will need these pages. */ +# define MADV_DONTNEED 4 /* Don't need these pages. */ +# define MADV_REMOVE 9 /* Remove these pages and resources. */ +# define MADV_DONTFORK 10 /* Do not inherit across fork. */ +# define MADV_DOFORK 11 /* Do inherit across fork. */ +#endif + +/* The POSIX people had to invent similar names for the same things. */ +#ifdef __USE_XOPEN2K +# define POSIX_MADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_MADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */ +#endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h new file mode 100644 index 000000000..422218a5f --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/msq.h @@ -0,0 +1,83 @@ +/* Copyright (C) 1995, 1996, 1997, 2000, 2002 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 _SYS_MSG_H +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead." +#endif + +#include <bits/types.h> +#include <bits/wordsize.h> + +/* Define options for message queue functions. */ +#define MSG_NOERROR 010000 /* no error if message is too big */ +#ifdef __USE_GNU +# define MSG_EXCEPT 020000 /* recv any msg except of specified type */ +#endif + +/* Types used in the structure definition. */ +typedef unsigned long int msgqnum_t; +typedef unsigned long int msglen_t; + +/* Structure of record for one message inside the kernel. + The type `struct msg' is opaque. */ +struct msqid_ds +{ + struct ipc_perm msg_perm; /* structure describing operation permission */ + __time_t msg_stime; /* time of last msgsnd command */ +#if __WORDSIZE == 32 + unsigned long int __unused1; +#endif + __time_t msg_rtime; /* time of last msgrcv command */ +#if __WORDSIZE == 32 + unsigned long int __unused2; +#endif + __time_t msg_ctime; /* time of last change */ +#if __WORDSIZE == 32 + unsigned long int __unused3; +#endif + unsigned long int __msg_cbytes; /* current number of bytes on queue */ + msgqnum_t msg_qnum; /* number of messages currently on queue */ + msglen_t msg_qbytes; /* max number of bytes allowed on queue */ + __pid_t msg_lspid; /* pid of last msgsnd() */ + __pid_t msg_lrpid; /* pid of last msgrcv() */ + unsigned long int __unused4; + unsigned long int __unused5; +}; + +#ifdef __USE_MISC + +# define msg_cbytes __msg_cbytes + +/* ipcs ctl commands */ +# define MSG_STAT 11 +# define MSG_INFO 12 + +/* buffer for msgctl calls IPC_INFO, MSG_INFO */ +struct msginfo + { + int msgpool; + int msgmap; + int msgmax; + int msgmnb; + int msgmni; + int msgssz; + int msgtql; + unsigned short int msgseg; + }; + +#endif /* __USE_MISC */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h new file mode 100644 index 000000000..9b1d993ee --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sem.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2002 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 _SYS_SEM_H +# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead." +#endif + +#include <sys/types.h> + +/* Flags for `semop'. */ +#define SEM_UNDO 0x1000 /* undo the operation on exit */ + +/* Commands for `semctl'. */ +#define GETPID 11 /* get sempid */ +#define GETVAL 12 /* get semval */ +#define GETALL 13 /* get all semval's */ +#define GETNCNT 14 /* get semncnt */ +#define GETZCNT 15 /* get semzcnt */ +#define SETVAL 16 /* set semval */ +#define SETALL 17 /* set all semval's */ + + +/* Data structure describing a set of semaphores. */ +struct semid_ds +{ + struct ipc_perm sem_perm; /* operation permission struct */ + __time_t sem_otime; /* last semop() time */ + unsigned long int __unused1; + __time_t sem_ctime; /* last time changed by semctl() */ + unsigned long int __unused2; + unsigned long int sem_nsems; /* number of semaphores in set */ + unsigned long int __unused3; + unsigned long int __unused4; +}; + +/* The user should define a union like the following to use it for arguments + for `semctl'. + + union semun + { + int val; <= value for SETVAL + struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET + unsigned short int *array; <= array for GETALL & SETALL + struct seminfo *__buf; <= buffer for IPC_INFO + }; + + Previous versions of this file used to define this union but this is + incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether + one must define the union or not. */ +#define _SEM_SEMUN_UNDEFINED 1 + +#ifdef __USE_MISC + +/* ipcs ctl cmds */ +# define SEM_STAT 18 +# define SEM_INFO 19 + +struct seminfo +{ + int semmap; + int semmni; + int semmns; + int semmnu; + int semmsl; + int semopm; + int semume; + int semusz; + int semvmx; + int semaem; +}; + +#endif /* __USE_MISC */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h new file mode 100644 index 000000000..3d8c05d21 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/shm.h @@ -0,0 +1,110 @@ +/* Copyright (C) 1995, 1996, 1997, 2000, 2002, 2004 + 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 _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize ()) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ +#if __WORDSIZE == 32 + unsigned long int __unused1; +#endif + __time_t shm_dtime; /* time of last shmdt() */ +#if __WORDSIZE == 32 + unsigned long int __unused2; +#endif + __time_t shm_ctime; /* time of last change by shmctl() */ +#if __WORDSIZE == 32 + unsigned long int __unused3; +#endif + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __unused4; + unsigned long int __unused5; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __unused1; + unsigned long int __unused2; + unsigned long int __unused3; + unsigned long int __unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h new file mode 100644 index 000000000..c0d5fe72d --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h @@ -0,0 +1,159 @@ +/* Copyright (C) 2002 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 _BITS_SIGCONTEXT_H +#define _BITS_SIGCONTEXT_H 1 + +#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H +# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead." +#endif + +#include <bits/wordsize.h> + +struct _fpreg +{ + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _fpxreg +{ + unsigned short significand[4]; + unsigned short exponent; + unsigned short padding[3]; +}; + +struct _xmmreg +{ + __uint32_t element[4]; +}; + + + +#if __WORDSIZE == 32 + +struct _fpstate +{ + /* Regular FPU environment. */ + __uint32_t cw; + __uint32_t sw; + __uint32_t tag; + __uint32_t ipoff; + __uint32_t cssel; + __uint32_t dataoff; + __uint32_t datasel; + struct _fpreg _st[8]; + unsigned short status; + unsigned short magic; + + /* FXSR FPU environment. */ + __uint32_t _fxsr_env[6]; + __uint32_t mxcsr; + __uint32_t reserved; + struct _fpxreg _fxsr_st[8]; + struct _xmmreg _xmm[8]; + __uint32_t padding[56]; +}; + +#ifndef sigcontext_struct +/* Kernel headers before 2.1.1 define a struct sigcontext_struct, but + we need sigcontext. Some packages have come to rely on + sigcontext_struct being defined on 32-bit x86, so define this for + their benefit. */ +# define sigcontext_struct sigcontext +#endif + +struct sigcontext +{ + unsigned short gs, __gsh; + unsigned short fs, __fsh; + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned long edi; + unsigned long esi; + unsigned long ebp; + unsigned long esp; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + unsigned long trapno; + unsigned long err; + unsigned long eip; + unsigned short cs, __csh; + unsigned long eflags; + unsigned long esp_at_signal; + unsigned short ss, __ssh; + struct _fpstate * fpstate; + unsigned long oldmask; + unsigned long cr2; +}; + +#else /* __WORDSIZE == 64 */ + +struct _fpstate +{ + /* FPU environment matching the 64-bit FXSAVE layout. */ + __uint16_t cwd; + __uint16_t swd; + __uint16_t ftw; + __uint16_t fop; + __uint64_t rip; + __uint64_t rdp; + __uint32_t mxcsr; + __uint32_t mxcr_mask; + struct _fpxreg _st[8]; + struct _xmmreg _xmm[16]; + __uint32_t padding[24]; +}; + +struct sigcontext +{ + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long rdi; + unsigned long rsi; + unsigned long rbp; + unsigned long rbx; + unsigned long rdx; + unsigned long rax; + unsigned long rcx; + unsigned long rsp; + unsigned long rip; + unsigned long eflags; + unsigned short cs; + unsigned short gs; + unsigned short fs; + unsigned short __pad0; + unsigned long err; + unsigned long trapno; + unsigned long oldmask; + unsigned long cr2; + struct _fpstate * fpstate; + unsigned long __reserved1 [8]; +}; + +#endif /* __WORDSIZE == 64 */ + +#endif /* _BITS_SIGCONTEXT_H */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h b/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h new file mode 100644 index 000000000..e756d7e8c --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/bits/stat.h @@ -0,0 +1,203 @@ +/* Copyright (C) 1999,2000,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. */ + +#ifndef _SYS_STAT_H +# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead." +#endif + +/* Versions of the `struct stat' data structure. */ +#define _STAT_VER_KERNEL 0 + +#if __WORDSIZE == 32 +# define _STAT_VER_SVR4 2 +# define _STAT_VER_LINUX 3 + +/* i386 versions of the `xmknod' interface. */ +# define _MKNOD_VER_LINUX 1 +# define _MKNOD_VER_SVR4 2 +# define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */ +#else +# define _STAT_VER_LINUX 1 + +/* x86-64 versions of the `xmknod' interface. */ +# define _MKNOD_VER_LINUX 0 +#endif + +#define _STAT_VER _STAT_VER_LINUX + +struct stat + { + __dev_t st_dev; /* Device. */ +#if __WORDSIZE == 32 + unsigned short int __pad1; +#endif +#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 + __ino_t st_ino; /* File serial number. */ +#else + __ino_t __st_ino; /* 32bit file serial number. */ +#endif +#if __WORDSIZE == 32 + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ +#else + __nlink_t st_nlink; /* Link count. */ + __mode_t st_mode; /* File mode. */ +#endif + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ +#if __WORDSIZE == 64 + int pad0; +#endif + __dev_t st_rdev; /* Device number, if device. */ +#if __WORDSIZE == 32 + unsigned short int __pad2; +#endif +#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 + __off_t st_size; /* Size of file, in bytes. */ +#else + __off64_t st_size; /* Size of file, in bytes. */ +#endif + __blksize_t st_blksize; /* Optimal block size for I/O. */ +#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64 + __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +#else + __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +#endif +#ifdef __USE_MISC + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +# define st_atime st_atim.tv_sec /* Backward compatibility. */ +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +#endif +#if __WORDSIZE == 64 + long int __unused[3]; +#else +# ifndef __USE_FILE_OFFSET64 + unsigned long int __unused4; + unsigned long int __unused5; +# else + __ino64_t st_ino; /* File serial number. */ +# endif +#endif + }; + +#ifdef __USE_LARGEFILE64 +/* Note stat64 has the same shape as stat for x86-64. */ +struct stat64 + { + __dev_t st_dev; /* Device. */ +#if __WORDSIZE == 64 + __ino64_t st_ino; /* File serial number. */ + __nlink_t st_nlink; /* Link count. */ + __mode_t st_mode; /* File mode. */ +#else + unsigned int __pad1; + __ino_t __st_ino; /* 32bit file serial number. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ +#endif + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ +#if __WORDSIZE == 64 + int pad0; + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ +#else + __dev_t st_rdev; /* Device number, if device. */ + unsigned int __pad2; + __off64_t st_size; /* Size of file, in bytes. */ +#endif + __blksize_t st_blksize; /* Optimal block size for I/O. */ + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ +#ifdef __USE_MISC + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the <sys/stat.h> header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +# define st_atime st_atim.tv_sec /* Backward compatibility. */ +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +#endif +#if __WORDSIZE == 64 + long int __unused[3]; +#else + __ino64_t st_ino; /* File serial number. */ +#endif + }; +#endif + +/* Tell code we have these members. */ +#define _STATBUF_ST_BLKSIZE +#define _STATBUF_ST_RDEV +/* Nanosecond resolution time values are supported. */ +#define _STATBUF_ST_NSEC + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* POSIX.1b objects. Note that these macros always evaluate to zero. But + they do it by enforcing the correct use of the macros. */ +#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode) +#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode) +#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode) + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/brk.c b/libc/sysdeps/unix/sysv/linux/x86_64/brk.c new file mode 100644 index 000000000..8b18c4dbb --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/brk.c @@ -0,0 +1,42 @@ +/* brk system call for Linux/x86_64. + Copyright (C) 1995, 1996, 2000, 2001, 2006 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 <errno.h> +#include <unistd.h> +#include <sysdep.h> + +/* This must be initialized data because commons can't have aliases. */ +void *__curbrk = 0; + +int +__brk (void *addr) +{ + void *newbrk; + + __curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr); + + if (newbrk < addr) + { + __set_errno (ENOMEM); + return -1; + } + + return 0; +} +weak_alias (__brk, brk) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/clone.S b/libc/sysdeps/unix/sysv/linux/x86_64/clone.S new file mode 100644 index 000000000..8a12b0903 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -0,0 +1,120 @@ +/* Copyright (C) 2001, 2002, 2003, 2004, 2005 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. */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> +#include <asm-syntax.h> +#include <bp-sym.h> +#include <bp-asm.h> + +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 + +/* The userland implementation is: + int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg), + the kernel entry is: + int clone (long flags, void *child_stack). + + The parameters are passed in register and on the stack from userland: + rdi: fn + rsi: child_stack + rdx: flags + rcx: arg + r8d: TID field in parent + r9d: thread pointer +%esp+8: TID field in child + + The kernel expects: + rax: system call number + rdi: flags + rsi: child_stack + rdx: TID field in parent + r10: TID field in child + r8: thread pointer */ + + + .text +ENTRY (BP_SYM (__clone)) + /* Sanity check arguments. */ + movq $-EINVAL,%rax + testq %rdi,%rdi /* no NULL function pointers */ + jz SYSCALL_ERROR_LABEL + testq %rsi,%rsi /* no NULL stack pointers */ + jz SYSCALL_ERROR_LABEL + + /* Insert the argument onto the new stack. */ + subq $16,%rsi + movq %rcx,8(%rsi) + + /* Save the function pointer. It will be popped off in the + child in the ebx frobbing below. */ + movq %rdi,0(%rsi) + + /* Do the system call. */ + movq %rdx, %rdi + movq %r8, %rdx + movq %r9, %r8 + movq 8(%rsp), %r10 + movl $SYS_ify(clone),%eax + + /* End FDE now, because in the child the unwind info will be + wrong. */ + cfi_endproc; + syscall + + testq %rax,%rax + jl SYSCALL_ERROR_LABEL + jz L(thread_start) + +L(pseudo_end): + ret + +L(thread_start): + /* Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. */ + xorl %ebp, %ebp + +#ifdef RESET_PID + testq $CLONE_THREAD, %rdi + jne 1f + testq $CLONE_VM, %rdi + movl $-1, %eax + jne 2f + movl $SYS_ify(getpid), %eax + syscall +2: movl %eax, %fs:PID + movl %eax, %fs:TID +1: +#endif + + /* Set up arguments for the function call. */ + popq %rax /* Function to call. */ + popq %rdi /* Argument. */ + call *%rax + /* Call exit with return value from function call. */ + movq %rax, %rdi + call HIDDEN_JUMPTARGET (_exit) + + cfi_startproc; +PSEUDO_END (BP_SYM (__clone)) + +weak_alias (BP_SYM (__clone), BP_SYM (clone)) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h b/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h new file mode 100644 index 000000000..cb647abf8 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-cache.h @@ -0,0 +1,25 @@ +/* Support for reading /etc/ld.so.cache files written by Linux ldconfig. + Copyright (C) 1999, 2000, 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. */ + +#define _DL_CACHE_DEFAULT_ID 0x303 + +#define _dl_cache_check_flags(flags) \ + ((flags) == _DL_CACHE_DEFAULT_ID) + +#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h> diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c new file mode 100644 index 000000000..6662a94d0 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c @@ -0,0 +1,5 @@ +#ifdef IS_IN_ldconfig +# include <sysdeps/i386/dl-procinfo.c> +#else +# include <sysdeps/generic/dl-procinfo.c> +#endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h new file mode 100644 index 000000000..31455204c --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h @@ -0,0 +1,5 @@ +#ifdef IS_IN_ldconfig +# include <sysdeps/unix/sysv/linux/i386/dl-procinfo.h> +#else +# include <sysdeps/generic/dl-procinfo.h> +#endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c b/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c new file mode 100644 index 000000000..a58d40a9c --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/get_clockfreq.c @@ -0,0 +1 @@ +#include "../i386/get_clockfreq.c" diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S new file mode 100644 index 000000000..4bbc7a4d2 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/getcontext.S @@ -0,0 +1,88 @@ +/* Save current context. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2002. + + 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 <sysdep.h> + +#include "ucontext_i.h" + +/* int __getcontext (ucontext_t *ucp) + + Saves the machine context in UCP such that when it is activated, + it appears as if __getcontext() returned again. + + This implementation is intended to be used for *synchronous* context + switches only. Therefore, it does not have to save anything + other than the PRESERVED state. */ + + +ENTRY(__getcontext) + /* Save the preserved registers, the registers used for passing + args, and the return address. */ + movq %rbx, oRBX(%rdi) + movq %rbp, oRBP(%rdi) + movq %r12, oR12(%rdi) + movq %r13, oR13(%rdi) + movq %r14, oR14(%rdi) + movq %r15, oR15(%rdi) + + movq %rdi, oRDI(%rdi) + movq %rsi, oRSI(%rdi) + movq %rdx, oRDX(%rdi) + movq %rcx, oRCX(%rdi) + movq %r8, oR8(%rdi) + movq %r9, oR9(%rdi) + + movq (%rsp), %rcx + movq %rcx, oRIP(%rdi) + leaq 8(%rsp), %rcx /* Exclude the return address. */ + movq %rcx, oRSP(%rdi) + + /* We have separate floating-point register content memory on the + stack. We use the __fpregs_mem block in the context. Set the + links up correctly. */ + + leaq oFPREGSMEM(%rdi), %rcx + movq %rcx, oFPREGS(%rdi) + /* Save the floating-point environment. */ + fnstenv (%rcx) + stmxcsr oMXCSR(%rdi) + + /* Save the current signal mask with + rt_sigprocmask (SIG_BLOCK, NULL, set,_NSIG/8). */ + leaq oSIGMASK(%rdi), %rdx + xorl %esi,%esi +#if SIG_BLOCK == 0 + xorl %edi, %edi +#else + movl $SIG_BLOCK, %edi +#endif + movl $_NSIG8,%r10d + movl $__NR_rt_sigprocmask, %eax + syscall + cmpq $-4095, %rax /* Check %rax for error. */ + jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ + + /* All done, return 0 for success. */ + xorl %eax, %eax +L(pseudo_end): + ret +PSEUDO_END(__getcontext) + +weak_alias (__getcontext, getcontext) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S b/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S new file mode 100644 index 000000000..84a99b040 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S @@ -0,0 +1,44 @@ +/* Copyright (C) 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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* For the calculation see asm/vsyscall.h. */ +#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 + + +ENTRY (__gettimeofday) + /* Align stack. */ + sub $0x8, %rsp + cfi_adjust_cfa_offset(8) + movq $VSYSCALL_ADDR_vgettimeofday, %rax + callq *%rax + /* Check error return. */ + cmpl $-4095, %eax + jae SYSCALL_ERROR_LABEL + +L(pseudo_end): + add $0x8, %rsp + cfi_adjust_cfa_offset(-8) + ret +PSEUDO_END(__gettimeofday) + +strong_alias (__gettimeofday, __gettimeofday_internal) +weak_alias (__gettimeofday, gettimeofday) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h b/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h new file mode 100644 index 000000000..ef11dc94d --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/kernel_stat.h @@ -0,0 +1,21 @@ +/* Definition of `struct stat' used in the kernel. + Copyright (C) 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. */ + +#define STAT_IS_KERNEL_STAT 1 +#define XSTAT_IS_XSTAT64 1 diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h b/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h new file mode 100644 index 000000000..f7f64eb1e --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/ldconfig.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2001, 2002 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 <sysdeps/generic/ldconfig.h> + +#define SYSDEP_KNOWN_INTERPRETER_NAMES \ + { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \ + { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 }, +#define SYSDEP_KNOWN_LIBRARY_NAMES \ + { "libc.so.6", FLAG_ELF_LIBC6 }, \ + { "libm.so.6", FLAG_ELF_LIBC6 }, diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed b/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed new file mode 100644 index 000000000..3f1530d31 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed @@ -0,0 +1,3 @@ +/LD_TRACE_LOADED_OBJECTS=1/a\ +add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out" +s_^\(RTLDLIST=\)\(.*lib\)\(\|64\)\(/[^/]*\)\(-x86-64\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \264\4\5\6"_ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c new file mode 100644 index 000000000..5deea7d1b --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/makecontext.c @@ -0,0 +1,113 @@ +/* Create new context. + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2002. + + 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 <sysdep.h> +#include <stdarg.h> +#include <stdint.h> +#include <ucontext.h> + +#include "ucontext_i.h" + +/* This implementation can handle any ARGC value but only + normal integer parameters. + makecontext sets up a stack and the registers for the + user context. The stack looks like this: + +-----------------------+ + | next context | + +-----------------------+ + | parameter 7-n | + +-----------------------+ + | trampoline address | + %rsp -> +-----------------------+ + + The registers are set up like this: + %rdi,%rsi,%rdx,%rcx,%r8,%r9: parameter 1 to 6 + %rbx : address of next context + %rsp : stack pointer. +*/ + +/* XXX: This implementation currently only handles integer arguments. + To handle long int and pointer arguments the va_arg arguments needs + to be changed to long and also the stdlib/tst-setcontext.c file needs + to be changed to pass long arguments to makecontext. */ + + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + extern void __start_context (void); + unsigned long int *sp, idx_uc_link; + va_list ap; + int i; + + /* Generate room on stack for parameter if needed and uc_link. */ + sp = (unsigned long int *) ((uintptr_t) ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size); + sp -= (argc > 6 ? argc - 6 : 0) + 1; + /* Align stack and make space for trampoline address. */ + sp = (unsigned long int *) ((((uintptr_t) sp) & -16L) - 8); + + idx_uc_link = (argc > 6 ? argc - 6 : 0) + 1; + + /* Setup context ucp. */ + /* Address to jump to. */ + ucp->uc_mcontext.gregs[REG_RIP] = (long int) func; + /* Setup rbx.*/ + ucp->uc_mcontext.gregs[REG_RBX] = (long int) &sp[idx_uc_link]; + ucp->uc_mcontext.gregs[REG_RSP] = (long int) sp; + + /* Setup stack. */ + sp[0] = (unsigned long int) &__start_context; + sp[idx_uc_link] = (unsigned long int) ucp->uc_link; + + va_start (ap, argc); + /* Handle arguments. */ + for (i = 0; i < argc; ++i) + switch (i) + { + case 0: + ucp->uc_mcontext.gregs [REG_RDI] = va_arg (ap, int); + break; + case 1: + ucp->uc_mcontext.gregs [REG_RSI] = va_arg (ap, int); + break; + case 2: + ucp->uc_mcontext.gregs [REG_RDX] = va_arg (ap, int); + break; + case 3: + ucp->uc_mcontext.gregs [REG_RCX] = va_arg (ap, int); + break; + case 4: + ucp->uc_mcontext.gregs [REG_R8] = va_arg (ap, int); + break; + case 5: + ucp->uc_mcontext.gregs [REG_R9] = va_arg (ap, int); + break; + default: + /* Put value on stack. */ + sp[(i - 5)] = va_arg (ap, int); + break; + } + va_end (ap); + +} + + +weak_alias (__makecontext, makecontext) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h new file mode 100644 index 000000000..0b244175a --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h @@ -0,0 +1,32 @@ +/* Low-level statistical profiling support function. Linux/x86-64 version. + Copyright (C) 2001, 2002 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 <signal.h> +#include <sigcontextinfo.h> + +static void +profil_counter (int signo, SIGCONTEXT scp) +{ + profil_count ((void *) GET_PC (scp)); + + /* This is a hack to prevent the compiler from implementing the + above function call as a sibcall. The sibcall would overwrite + the signal context. */ + asm volatile (""); +} diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c b/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c new file mode 100644 index 000000000..5a49af3fa --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/readelflib.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 1999 and + Jakub Jelinek <jakub@redhat.com>, 1999. + + 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. */ + + +int process_elf32_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, + void *file_contents, size_t file_length); +int process_elf64_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, + void *file_contents, size_t file_length); + +/* Returns 0 if everything is ok, != 0 in case of error. */ +int +process_elf_file (const char *file_name, const char *lib, int *flag, + unsigned int *osversion, char **soname, void *file_contents, + size_t file_length) +{ + ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; + int ret; + + if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) + return process_elf32_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + else + { + ret = process_elf64_file (file_name, lib, flag, osversion, soname, + file_contents, file_length); + /* x86-64 64bit libraries are always libc.so.6+. */ + if (!ret) + *flag = FLAG_X8664_LIB64|FLAG_ELF_LIBC6; + return ret; + } +} + +#undef __ELF_NATIVE_CLASS +#undef process_elf_file +#define process_elf_file process_elf32_file +#define __ELF_NATIVE_CLASS 32 +#include "elf/readelflib.c" + +#undef __ELF_NATIVE_CLASS +#undef process_elf_file +#define process_elf_file process_elf64_file +#define __ELF_NATIVE_CLASS 64 +#include "elf/readelflib.c" diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/recv.c b/libc/sysdeps/unix/sysv/linux/x86_64/recv.c new file mode 100644 index 000000000..2fa1794d3 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/recv.c @@ -0,0 +1,42 @@ +/* Copyright (C) 2001, 2002 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 <errno.h> +#include <sys/socket.h> +#include <sysdep-cancel.h> + +/* Read N bytes into BUF from socket FD. + Returns the number read or -1 for errors. */ + +ssize_t +__libc_recv (int fd, void *buf, size_t n, int flags) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL); + + int oldtype = LIBC_CANCEL_ASYNC (); + + ssize_t result = INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_recv, __recv) +weak_alias (__recv, recv) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h b/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h new file mode 100644 index 000000000..50f589d0d --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/register-dump.h @@ -0,0 +1,346 @@ +/* Dump registers. + 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 <sys/uio.h> +#include <stdio-common/_itoa.h> + +/* We will print the register dump in this format: + + RAX: XXXXXXXXXXXXXXXX RBX: XXXXXXXXXXXXXXXX RCX: XXXXXXXXXXXXXXXX + RDX: XXXXXXXXXXXXXXXX RSI: XXXXXXXXXXXXXXXX RDI: XXXXXXXXXXXXXXXX + RBP: XXXXXXXXXXXXXXXX R8 : XXXXXXXXXXXXXXXX R9 : XXXXXXXXXXXXXXXX + R10: XXXXXXXXXXXXXXXX R11: XXXXXXXXXXXXXXXX R12: XXXXXXXXXXXXXXXX + R13: XXXXXXXXXXXXXXXX R14: XXXXXXXXXXXXXXXX R15: XXXXXXXXXXXXXXXX + RSP: XXXXXXXXXXXXXXXX + + RIP: XXXXXXXXXXXXXXXX EFLAGS: XXXXXXXX + + CS: XXXX DS: XXXX ES: XXXX FS: XXXX GS: XXXX + + Trap: XXXXXXXX Error: XXXXXXXX OldMask: XXXXXXXX + RSP/SIGNAL: XXXXXXXXXXXXXXXX CR2: XXXXXXXX + + FPUCW: XXXXXXXX FPUSW: XXXXXXXX TAG: XXXXXXXX + IPOFF: XXXXXXXX CSSEL: XXXX DATAOFF: XXXXXXXX DATASEL: XXXX + + ST(0) XXXX XXXXXXXXXXXXXXXX ST(1) XXXX XXXXXXXXXXXXXXXX + ST(2) XXXX XXXXXXXXXXXXXXXX ST(3) XXXX XXXXXXXXXXXXXXXX + ST(4) XXXX XXXXXXXXXXXXXXXX ST(5) XXXX XXXXXXXXXXXXXXXX + ST(6) XXXX XXXXXXXXXXXXXXXX ST(7) XXXX XXXXXXXXXXXXXXXX + + mxcsr: XXXX + XMM0 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM1 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM2 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM3 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM4 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM5 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM6 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM7 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM8 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM9 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM10: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM11: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM12: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM13: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XMM14: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XMM15: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + */ + +static void +hexvalue (unsigned long int value, char *buf, size_t len) +{ + char *cp = _itoa_word (value, buf + len, 16, 0); + while (cp > buf) + *--cp = '0'; +} + +static void +register_dump (int fd, struct ucontext *ctx) +{ + char regs[25][16]; + char fpregs[30][8]; + char xmmregs[16][32]; + struct iovec iov[147]; + size_t nr = 0; + int i; + +#define ADD_STRING(str) \ + iov[nr].iov_base = (char *) str; \ + iov[nr].iov_len = strlen (str); \ + ++nr +#define ADD_MEM(str, len) \ + iov[nr].iov_base = str; \ + iov[nr].iov_len = len; \ + ++nr + + /* Generate strings of register contents. */ + hexvalue (ctx->uc_mcontext.gregs[REG_RAX], regs[0], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RBX], regs[1], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RCX], regs[2], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RDX], regs[3], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RSI], regs[4], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RDI], regs[5], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RBP], regs[6], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[7], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[8], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[9], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[10], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[11], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[12], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[13], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[14], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RSP], regs[15], 16); + hexvalue (ctx->uc_mcontext.gregs[REG_RIP], regs[16], 16); + + hexvalue (ctx->uc_mcontext.gregs[REG_EFL], regs[17], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_CSGSFS] & 0xffff, regs[18], 4); + hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 16) & 0xffff, regs[19], 4); + hexvalue ((ctx->uc_mcontext.gregs[REG_CSGSFS] >> 32) & 0xffff, regs[20], 4); + /* hexvalue (ctx->ss, regs[23], 4); */ + hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[21], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[22], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_OLDMASK], regs[23], 8); + hexvalue (ctx->uc_mcontext.gregs[REG_CR2], regs[24], 8); + + /* Generate the output. */ + ADD_STRING ("Register dump:\n\n RAX: "); + ADD_MEM (regs[0], 16); + ADD_STRING (" RBX: "); + ADD_MEM (regs[1], 16); + ADD_STRING (" RCX: "); + ADD_MEM (regs[2], 16); + ADD_STRING ("\n RDX: "); + ADD_MEM (regs[3], 16); + ADD_STRING (" RSI: "); + ADD_MEM (regs[4], 16); + ADD_STRING (" RDI: "); + ADD_MEM (regs[5], 16); + ADD_STRING ("\n RBP: "); + ADD_MEM (regs[6], 16); + ADD_STRING (" R8 : "); + ADD_MEM (regs[7], 16); + ADD_STRING (" R9 : "); + ADD_MEM (regs[8], 16); + ADD_STRING ("\n R10: "); + ADD_MEM (regs[9], 16); + ADD_STRING (" R11: "); + ADD_MEM (regs[10], 16); + ADD_STRING (" R12: "); + ADD_MEM (regs[11], 16); + ADD_STRING ("\n R13: "); + ADD_MEM (regs[12], 16); + ADD_STRING (" R14: "); + ADD_MEM (regs[13], 16); + ADD_STRING (" R15: "); + ADD_MEM (regs[14], 16); + ADD_STRING ("\n RSP: "); + ADD_MEM (regs[15], 16); + ADD_STRING ("\n\n RIP: "); + ADD_MEM (regs[16], 16); + ADD_STRING (" EFLAGS: "); + ADD_MEM (regs[17], 8); + ADD_STRING ("\n\n CS: "); + ADD_MEM (regs[18], 4); + ADD_STRING (" FS: "); + ADD_MEM (regs[19], 4); + ADD_STRING (" GS: "); + ADD_MEM (regs[20], 4); + /* + ADD_STRING (" SS: "); + ADD_MEM (regs[23], 4); + */ + ADD_STRING ("\n\n Trap: "); + ADD_MEM (regs[21], 8); + ADD_STRING (" Error: "); + ADD_MEM (regs[22], 8); + ADD_STRING (" OldMask: "); + ADD_MEM (regs[23], 8); + ADD_STRING (" CR2: "); + ADD_MEM (regs[24], 8); + + if (ctx->uc_mcontext.fpregs != NULL) + { + + /* Generate output for the FPU control/status registers. */ + hexvalue (ctx->uc_mcontext.fpregs->cwd, fpregs[0], 8); + hexvalue (ctx->uc_mcontext.fpregs->swd, fpregs[1], 8); + hexvalue (ctx->uc_mcontext.fpregs->ftw, fpregs[2], 8); + hexvalue (ctx->uc_mcontext.fpregs->rip, fpregs[3], 8); + hexvalue (ctx->uc_mcontext.fpregs->rdp, fpregs[4], 8); + + ADD_STRING ("\n\n FPUCW: "); + ADD_MEM (fpregs[0], 8); + ADD_STRING (" FPUSW: "); + ADD_MEM (fpregs[1], 8); + ADD_STRING (" TAG: "); + ADD_MEM (fpregs[2], 8); + ADD_STRING ("\n RIP: "); + ADD_MEM (fpregs[3], 8); + ADD_STRING (" RDP: "); + ADD_MEM (fpregs[4], 8); + + /* Now the real FPU registers. */ + hexvalue (ctx->uc_mcontext.fpregs->_st[0].exponent, fpregs[5], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[0].significand[2], fpregs[6], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[0].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[0].significand[0], fpregs[7], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[1].exponent, fpregs[8], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[1].significand[2], fpregs[9], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[1].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[1].significand[0], fpregs[10], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[2].exponent, fpregs[11], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[2].significand[2], fpregs[12], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[2].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[2].significand[0], fpregs[13], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[3].exponent, fpregs[14], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[3].significand[2], fpregs[15], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[3].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[3].significand[0], fpregs[16], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[4].exponent, fpregs[17], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[4].significand[2], fpregs[18], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[4].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[4].significand[0], fpregs[19], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[5].exponent, fpregs[20], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[5].significand[2], fpregs[21], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[5].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[5].significand[0], fpregs[22], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[6].exponent, fpregs[23], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[6].significand[2], fpregs[24], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[6].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[6].significand[0], fpregs[25], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[7].exponent, fpregs[26], 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[3] << 16 + | ctx->uc_mcontext.fpregs->_st[7].significand[2], fpregs[27], + 8); + hexvalue (ctx->uc_mcontext.fpregs->_st[7].significand[1] << 16 + | ctx->uc_mcontext.fpregs->_st[7].significand[0], fpregs[28], + 8); + + hexvalue (ctx->uc_mcontext.fpregs->mxcsr, fpregs[29], 4); + + for (i = 0; i < 16; i++) + hexvalue (ctx->uc_mcontext.fpregs->_xmm[i].element[3] << 24 + | ctx->uc_mcontext.fpregs->_xmm[i].element[2] << 16 + | ctx->uc_mcontext.fpregs->_xmm[i].element[1] << 8 + | ctx->uc_mcontext.fpregs->_xmm[i].element[0], xmmregs[i], + 32); + + + ADD_STRING ("\n\n ST(0) "); + ADD_MEM (fpregs[5], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[6], 8); + ADD_MEM (fpregs[7], 8); + ADD_STRING (" ST(1) "); + ADD_MEM (fpregs[8], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[9], 8); + ADD_MEM (fpregs[10], 8); + ADD_STRING ("\n ST(2) "); + ADD_MEM (fpregs[11], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[12], 8); + ADD_MEM (fpregs[13], 8); + ADD_STRING (" ST(3) "); + ADD_MEM (fpregs[14], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[15], 8); + ADD_MEM (fpregs[16], 8); + ADD_STRING ("\n ST(4) "); + ADD_MEM (fpregs[17], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[18], 8); + ADD_MEM (fpregs[19], 8); + ADD_STRING (" ST(5) "); + ADD_MEM (fpregs[20], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[21], 8); + ADD_MEM (fpregs[22], 8); + ADD_STRING ("\n ST(6) "); + ADD_MEM (fpregs[23], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[24], 8); + ADD_MEM (fpregs[25], 8); + ADD_STRING (" ST(7) "); + ADD_MEM (fpregs[27], 4); + ADD_STRING (" "); + ADD_MEM (fpregs[27], 8); + ADD_MEM (fpregs[28], 8); + + ADD_STRING ("\n mxcsr: "); + ADD_MEM (fpregs[29], 4); + + ADD_STRING ("\n XMM0: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM1: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM2: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM3: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM4: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM5: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM6: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM7: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM8: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM9: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM10: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM11: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM12: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM13: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING ("\n XMM14: "); + ADD_MEM (xmmregs[0], 32); + ADD_STRING (" XMM15: "); + ADD_MEM (xmmregs[0], 32); + + } + + ADD_STRING ("\n"); + + /* Write the stuff out. */ + writev (fd, iov, nr); +} + + +#define REGISTER_DUMP register_dump (fd, ctx) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/send.c b/libc/sysdeps/unix/sysv/linux/x86_64/send.c new file mode 100644 index 000000000..c484ce69f --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/send.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2001, 2002 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 <errno.h> +#include <sys/socket.h> +#include <sysdep-cancel.h> + +/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ +ssize_t +__libc_send (int fd, const void *buf, size_t n, int flags) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, NULL); + + int oldtype = LIBC_CANCEL_ASYNC (); + + ssize_t result = INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, NULL); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_send, __send) +libc_hidden_weak (__send) +weak_alias (__send, send) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S new file mode 100644 index 000000000..61fc07f44 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/setcontext.S @@ -0,0 +1,105 @@ +/* Install given context. + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2002. + + 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 <sysdep.h> + +#include "ucontext_i.h" + + +/* int __setcontext (const ucontext_t *ucp) + + Restores the machine context in UCP and thereby resumes execution + in that context. + + This implementation is intended to be used for *synchronous* context + switches only. Therefore, it does not have to restore anything + other than the PRESERVED state. */ + +ENTRY(__setcontext) + /* Save argument since syscall will destroy it. */ + pushq %rdi + cfi_adjust_cfa_offset(8) + + /* Set the signal mask with + rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */ + leaq oSIGMASK(%rdi), %rsi + xorl %edx, %edx + movl $SIG_SETMASK, %edi + movl $_NSIG8,%r10d + movl $__NR_rt_sigprocmask, %eax + syscall + popq %rdi /* Reload %rdi, adjust stack. */ + cfi_adjust_cfa_offset(-8) + cmpq $-4095, %rax /* Check %rax for error. */ + jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ + + /* Restore the floating-point context. Not the registers, only the + rest. */ + movq oFPREGS(%rdi), %rcx + fldenv (%rcx) + ldmxcsr oMXCSR(%rdi) + + + /* Load the new stack pointer, the preserved registers and + registers used for passing args. */ + cfi_def_cfa(%rdi, 0) + cfi_offset(%rbx,oRBX) + cfi_offset(%rbp,oRBP) + cfi_offset(%r12,oR12) + cfi_offset(%r13,oR13) + cfi_offset(%r14,oR14) + cfi_offset(%r15,oR15) + cfi_offset(%rsp,oRSP) + cfi_offset(%rip,oRIP) + + movq oRSP(%rdi), %rsp + movq oRBX(%rdi), %rbx + movq oRBP(%rdi), %rbp + movq oR12(%rdi), %r12 + movq oR13(%rdi), %r13 + movq oR14(%rdi), %r14 + movq oR15(%rdi), %r15 + + /* The following ret should return to the address set with + getcontext. Therefore push the address on the stack. */ + movq oRIP(%rdi), %rcx + pushq %rcx + + movq oRSI(%rdi), %rsi + movq oRDX(%rdi), %rdx + movq oRCX(%rdi), %rcx + movq oR8(%rdi), %r8 + movq oR9(%rdi), %r9 + + /* Setup finally %rdi. */ + movq oRDI(%rdi), %rdi + + /* End FDE here, we fall into another context. */ + cfi_endproc + cfi_startproc + + /* Clear rax to indicate success. */ + xorl %eax, %eax + +L(pseudo_end): + ret +PSEUDO_END(__setcontext) + +weak_alias (__setcontext, setcontext) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c new file mode 100644 index 000000000..d6f4558ce --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -0,0 +1,112 @@ +/* POSIX.1 `sigaction' call for Linux/x86-64. + Copyright (C) 2001, 2002, 2003, 2005 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 <sysdep.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> +#include <string.h> + +#include <sysdep.h> +#include <sys/syscall.h> + +#include <kernel-features.h> + +/* The difference here is that the sigaction structure used in the + kernel is not the same as we use in the libc. Therefore we must + translate it here. */ +#include <kernel_sigaction.h> + +/* We do not globally define the SA_RESTORER flag so do it here. */ +#define SA_RESTORER 0x04000000 + +/* Using the hidden attribute here does not change the code but it + helps to avoid warnings. */ +#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \ + && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE +extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; +#else +static void restore_rt (void) asm ("__restore_rt"); +#endif + + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +{ + int result; + struct kernel_sigaction kact, koact; + + if (act) + { + kact.k_sa_handler = act->sa_handler; + memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); + kact.sa_flags = act->sa_flags | SA_RESTORER; + + kact.sa_restorer = &restore_rt; + } + + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + result = INLINE_SYSCALL (rt_sigaction, 4, + sig, act ? __ptrvalue (&kact) : NULL, + oact ? __ptrvalue (&koact) : NULL, _NSIG / 8); + if (oact && result >= 0) + { + oact->sa_handler = koact.k_sa_handler; + memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); + oact->sa_flags = koact.sa_flags; + oact->sa_restorer = koact.sa_restorer; + } + return result; +} +libc_hidden_def (__libc_sigaction) + +#ifdef WRAPPER_INCLUDE +# include WRAPPER_INCLUDE +#endif + +#ifndef LIBC_SIGACTION +weak_alias (__libc_sigaction, __sigaction) +libc_hidden_weak (__sigaction) +weak_alias (__libc_sigaction, sigaction) +#endif + +/* NOTE: Please think twice before making any changes to the bits of + code below. GDB needs some intimate knowledge about it to + recognize them as signal trampolines, and make backtraces through + signal handlers work right. Important are both the names + (__restore_rt) and the exact instruction sequence. + If you ever feel the need to make any changes, please notify the + appropriate GDB maintainer. */ + +#define RESTORE(name, syscall) RESTORE2 (name, syscall) +# define RESTORE2(name, syscall) \ +asm \ + ( \ + ".align 16\n" \ + CFI_STARTPROC "\n" \ + "__" #name ":\n" \ + " movq $" #syscall ", %rax\n" \ + " syscall\n" \ + CFI_ENDPROC "\n" \ + ); +/* The return code for realtime-signals. */ +RESTORE (restore_rt, __NR_rt_sigreturn) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h new file mode 100644 index 000000000..11493c580 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h @@ -0,0 +1,26 @@ +/* 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. */ + +#define SIGCONTEXT siginfo_t *_si, struct ucontext * +#define SIGCONTEXT_EXTRA_ARGS _si, +#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RIP]) +#define GET_FRAME(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RBP]) +#define GET_STACK(ctx) ((void *) (ctx)->uc_mcontext.gregs[REG_RSP]) + +#define CALL_SIGHANDLER(handler, signo, ctx) \ + (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx)) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c new file mode 100644 index 000000000..c7ddb1fbd --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigpending.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/ia64/sigpending.c> diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c b/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c new file mode 100644 index 000000000..bc0927f45 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/ia64/sigprocmask.c> diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S new file mode 100644 index 000000000..fc7996ccd --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/swapcontext.S @@ -0,0 +1,123 @@ +/* Save current context and install the given one. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>, 2002. + + 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 <sysdep.h> + +#include "ucontext_i.h" + + +/* int __swapcontext (ucontext_t *oucp, const ucontext_t *ucp); + + Saves the machine context in oucp such that when it is activated, + it appears as if __swapcontextt() returned again, restores the + machine context in ucp and thereby resumes execution in that + context. + + This implementation is intended to be used for *synchronous* context + switches only. Therefore, it does not have to save anything + other than the PRESERVED state. */ + +ENTRY(__swapcontext) + /* Save the preserved registers, the registers used for passing args, + and the return address. */ + movq %rbx, oRBX(%rdi) + movq %rbp, oRBP(%rdi) + movq %r12, oR12(%rdi) + movq %r13, oR13(%rdi) + movq %r14, oR14(%rdi) + movq %r15, oR15(%rdi) + + movq %rdi, oRDI(%rdi) + movq %rsi, oRSI(%rdi) + movq %rdx, oRDX(%rdi) + movq %rcx, oRCX(%rdi) + movq %r8, oR8(%rdi) + movq %r9, oR9(%rdi) + + movq (%rsp), %rcx + movq %rcx, oRIP(%rdi) + leaq 8(%rsp), %rcx /* Exclude the return address. */ + movq %rcx, oRSP(%rdi) + + /* We have separate floating-point register content memory on the + stack. We use the __fpregs_mem block in the context. Set the + links up correctly. */ + leaq oFPREGSMEM(%rdi), %rcx + movq %rcx, oFPREGS(%rdi) + /* Save the floating-point environment. */ + fnstenv (%rcx) + stmxcsr oMXCSR(%rdi) + + + /* The syscall destroys some registers, save them. */ + movq %rsi, %r12 + + /* Save the current signal mask and install the new one with + rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8). */ + leaq oSIGMASK(%rdi), %rdx + leaq oSIGMASK(%rsi), %rsi + movl $SIG_SETMASK, %edi + movl $_NSIG8,%r10d + movl $__NR_rt_sigprocmask, %eax + syscall + cmpq $-4095, %rax /* Check %rax for error. */ + jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ + + /* Restore destroyed registers. */ + movq %r12, %rsi + + /* Restore the floating-point context. Not the registers, only the + rest. */ + movq oFPREGS(%rsi), %rcx + fldenv (%rcx) + ldmxcsr oMXCSR(%rsi) + + /* Load the new stack pointer and the preserved registers. */ + movq oRSP(%rsi), %rsp + movq oRBX(%rsi), %rbx + movq oRBP(%rsi), %rbp + movq oR12(%rsi), %r12 + movq oR13(%rsi), %r13 + movq oR14(%rsi), %r14 + movq oR15(%rsi), %r15 + + /* The following ret should return to the address set with + getcontext. Therefore push the address on the stack. */ + movq oRIP(%rsi), %rcx + pushq %rcx + + /* Setup registers used for passing args. */ + movq oRDI(%rsi), %rdi + movq oRDX(%rsi), %rdx + movq oRCX(%rsi), %rcx + movq oR8(%rsi), %r8 + movq oR9(%rsi), %r9 + + /* Setup finally %rsi. */ + movq oRSI(%rsi), %rsi + + /* Clear rax to indicate success. */ + xorl %eax, %eax + +L(pseudo_end): + ret +PSEUDO_END(__swapcontext) + +weak_alias (__swapcontext, swapcontext) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h new file mode 100644 index 000000000..8abbf7546 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/debugreg.h @@ -0,0 +1,88 @@ +/* Copyright (C) 2001, 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. */ + +#ifndef _SYS_DEBUGREG_H +#define _SYS_DEBUGREG_H 1 +#include <bits/wordsize.h> + +/* Indicate the register numbers for a number of the specific + debug registers. Registers 0-3 contain the addresses we wish to trap on */ +#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */ +#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */ + +#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */ +#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */ + +/* Define a few things for the status register. We can use this to determine + which debugging register was responsible for the trap. The other bits + are either reserved or not of interest to us. */ + +#define DR_TRAP0 (0x1) /* db0 */ +#define DR_TRAP1 (0x2) /* db1 */ +#define DR_TRAP2 (0x4) /* db2 */ +#define DR_TRAP3 (0x8) /* db3 */ + +#define DR_STEP (0x4000) /* single-step */ +#define DR_SWITCH (0x8000) /* task switch */ + +/* Now define a bunch of things for manipulating the control register. + The top two bytes of the control register consist of 4 fields of 4 + bits - each field corresponds to one of the four debug registers, + and indicates what types of access we trap on, and how large the data + field is that we are looking at */ + +#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */ +#define DR_CONTROL_SIZE 4 /* 4 control bits per register */ + +#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */ +#define DR_RW_WRITE (0x1) +#define DR_RW_READ (0x3) + +#define DR_LEN_1 (0x0) /* Settings for data length to trap on */ +#define DR_LEN_2 (0x4) +#define DR_LEN_4 (0xC) +#define DR_LEN_8 (0x8) + +/* The low byte to the control register determine which registers are + enabled. There are 4 fields of two bits. One bit is "local", meaning + that the processor will reset the bit after a task switch and the other + is global meaning that we have to explicitly reset the bit. With linux, + you can use either one, since we explicitly zero the register when we enter + kernel mode. */ + +#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */ +#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */ +#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */ + +#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */ +#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */ + +/* The second byte to the control register has a few special + things. */ + + + +#if __WORDSIZE == 64 +# define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */ +#else +# define DR_CONTROL_RESERVED (0x00FC00U) /* Reserved */ +#endif +#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */ +#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */ + +#endif /* sys/debugreg.h */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h new file mode 100644 index 000000000..02672d3c7 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h @@ -0,0 +1,110 @@ +/* Copyright (C) 2002,2003,2004,2005,2006 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 _SYS_EPOLL_H +#define _SYS_EPOLL_H 1 + +#include <stdint.h> +#include <sys/types.h> + + +enum EPOLL_EVENTS + { + EPOLLIN = 0x001, +#define EPOLLIN EPOLLIN + EPOLLPRI = 0x002, +#define EPOLLPRI EPOLLPRI + EPOLLOUT = 0x004, +#define EPOLLOUT EPOLLOUT + EPOLLRDNORM = 0x040, +#define EPOLLRDNORM EPOLLRDNORM + EPOLLRDBAND = 0x080, +#define EPOLLRDBAND EPOLLRDBAND + EPOLLWRNORM = 0x100, +#define EPOLLWRNORM EPOLLWRNORM + EPOLLWRBAND = 0x200, +#define EPOLLWRBAND EPOLLWRBAND + EPOLLMSG = 0x400, +#define EPOLLMSG EPOLLMSG + EPOLLERR = 0x008, +#define EPOLLERR EPOLLERR + EPOLLHUP = 0x010, +#define EPOLLHUP EPOLLHUP + EPOLLONESHOT = (1 << 30), +#define EPOLLONESHOT EPOLLONESHOT + EPOLLET = (1 << 31) +#define EPOLLET EPOLLET + }; + + +/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */ +#define EPOLL_CTL_ADD 1 /* Add a file decriptor to the interface. */ +#define EPOLL_CTL_DEL 2 /* Remove a file decriptor from the interface. */ +#define EPOLL_CTL_MOD 3 /* Change file decriptor epoll_event structure. */ + + +typedef union epoll_data +{ + void *ptr; + int fd; + uint32_t u32; + uint64_t u64; +} epoll_data_t; + +struct epoll_event +{ + uint32_t events; /* Epoll events */ + epoll_data_t data; /* User data variable */ +} __attribute__ ((__packed__)); + + +__BEGIN_DECLS + +/* Creates an epoll instance. Returns an fd for the new instance. + The "size" parameter is a hint specifying the number of file + descriptors to be associated with the new instance. The fd + returned by epoll_create() should be closed with close(). */ +extern int epoll_create (int __size) __THROW; + + +/* Manipulate an epoll instance "epfd". Returns 0 in case of success, + -1 in case of error ( the "errno" variable will contain the + specific error code ) The "op" parameter is one of the EPOLL_CTL_* + constants defined above. The "fd" parameter is the target of the + operation. The "event" parameter describes which events the caller + is interested in and any associated user data. */ +extern int epoll_ctl (int __epfd, int __op, int __fd, + struct epoll_event *__event) __THROW; + + +/* Wait for events on an epoll instance "epfd". Returns the number of + triggered events returned in "events" buffer. Or -1 in case of + error with the "errno" variable set to the specific error code. The + "events" parameter is a buffer that will contain triggered + events. The "maxevents" is the maximum number of events to be + returned ( usually size of "events" ). The "timeout" parameter + specifies the maximum wait time in milliseconds (-1 == infinite). + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern int epoll_wait (int __epfd, struct epoll_event *__events, + int __maxevents, int __timeout); + +__END_DECLS + +#endif /* sys/epoll.h */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h new file mode 100644 index 000000000..802a0dfb4 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/io.h @@ -0,0 +1,181 @@ +/* Copyright (C) 1996, 2000, 2002 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 _SYS_IO_H +#define _SYS_IO_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* If TURN_ON is TRUE, request for permission to do direct i/o on the + port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O + permission off for that range. This call requires root privileges. + + Portability note: not all Linux platforms support this call. Most + platforms based on the PC I/O architecture probably will, however. + E.g., Linux/Alpha for Alpha PCs supports this. */ +extern int ioperm (unsigned long int __from, unsigned long int __num, + int __turn_on) __THROW; + +/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to + access any I/O port is granted. This call requires root + privileges. */ +extern int iopl (int __level) __THROW; + +#if defined __GNUC__ && __GNUC__ >= 2 + +static __inline unsigned char +inb (unsigned short int port) +{ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned char +inb_p (unsigned short int port) +{ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned short int +inw (unsigned short int port) +{ + unsigned short _v; + + __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned short int +inw_p (unsigned short int port) +{ + unsigned short int _v; + + __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned int +inl (unsigned short int port) +{ + unsigned int _v; + + __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned int +inl_p (unsigned short int port) +{ + unsigned int _v; + __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline void +outb (unsigned char value, unsigned short int port) +{ + __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port)); +} + +static __inline void +outb_p (unsigned char value, unsigned short int port) +{ + __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value), + "Nd" (port)); +} + +static __inline void +outw (unsigned short int value, unsigned short int port) +{ + __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port)); + +} + +static __inline void +outw_p (unsigned short int value, unsigned short int port) +{ + __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value), + "Nd" (port)); +} + +static __inline void +outl (unsigned int value, unsigned short int port) +{ + __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port)); +} + +static __inline void +outl_p (unsigned int value, unsigned short int port) +{ + __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value), + "Nd" (port)); +} + +static __inline void +insb (unsigned short int port, void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +static __inline void +insw (unsigned short int port, void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +static __inline void +insl (unsigned short int port, void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +static __inline void +outsb (unsigned short int port, const void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +static __inline void +outsw (unsigned short int port, const void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +static __inline void +outsl (unsigned short int port, const void *addr, unsigned long int count) +{ + __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr), + "=c" (count):"d" (port), "0" (addr), "1" (count)); +} + +#endif /* GNU C */ + +__END_DECLS +#endif /* _SYS_IO_H */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h new file mode 100644 index 000000000..382fa92ee --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/perm.h @@ -0,0 +1,36 @@ +/* Copyright (C) 1996, 1999, 2001 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 _SYS_PERM_H + +#define _SYS_PERM_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Set port input/output permissions. */ +extern int ioperm (unsigned long int __from, unsigned long int __num, + int __turn_on) __THROW; + + +/* Change I/O privilege level. */ +extern int iopl (int __level) __THROW; + +__END_DECLS + +#endif /* _SYS_PERM_H */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h new file mode 100644 index 000000000..853d7db49 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/procfs.h @@ -0,0 +1,142 @@ +/* Copyright (C) 2001, 2004 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 _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somewhat modelled after the file of the same name on SVR4 + systems. It provides a definition of the core file format for ELF + used on Linux. It doesn't have anything to do with the /proc file + system, even though Linux has one. + + Anyway, the whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for anything other than + GDB unless you know what you are doing. */ + +#include <features.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/user.h> + +__BEGIN_DECLS + +/* Type for a general-purpose register. */ +typedef unsigned long elf_greg_t; + +/* And the whole bunch of them. We could have used `struct + user_regs_struct' directly in the typedef, but tradition says that + the register set is an array, which does have some peculiar + semantics, so leave it that way. */ +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +#if __WORDSIZE == 32 +/* Register set for the floating-point registers. */ +typedef struct user_fpregs_struct elf_fpregset_t; + +/* Register set for the extended floating-point registers. Includes + the Pentium III SSE registers in addition to the classic + floating-point stuff. */ +typedef struct user_fpxregs_struct elf_fpxregset_t; +#else +/* Register set for the extended floating-point registers. Includes + the Pentium III SSE registers in addition to the classic + floating-point stuff. */ +typedef struct user_fpregs_struct elf_fpregset_t; +#endif + +/* Signal info. */ +struct elf_siginfo + { + int si_signo; /* Signal number. */ + int si_code; /* Extra code. */ + int si_errno; /* Errno. */ + }; + + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with Linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + GDB doesn't really use excluded. */ + +struct elf_prstatus + { + struct elf_siginfo pr_info; /* Info associated with signal. */ + short int pr_cursig; /* Current signal. */ + unsigned long int pr_sigpend; /* Set of pending signals. */ + unsigned long int pr_sighold; /* Set of held signals. */ + __pid_t pr_pid; + __pid_t pr_ppid; + __pid_t pr_pgrp; + __pid_t pr_sid; + struct timeval pr_utime; /* User time. */ + struct timeval pr_stime; /* System time. */ + struct timeval pr_cutime; /* Cumulative user time. */ + struct timeval pr_cstime; /* Cumulative system time. */ + elf_gregset_t pr_reg; /* GP registers. */ + int pr_fpvalid; /* True if math copro being used. */ + }; + + +#define ELF_PRARGSZ (80) /* Number of chars for args. */ + +struct elf_prpsinfo + { + char pr_state; /* Numeric process state. */ + char pr_sname; /* Char for pr_state. */ + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned long int pr_flag; /* Flags. */ +#if __WORDSIZE == 32 + unsigned short int pr_uid; + unsigned short int pr_gid; +#else + unsigned int pr_uid; + unsigned int pr_gid; +#endif + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + + +/* The rest of this file provides the types for emulation of the + Solaris <proc_service.h> interfaces that should be implemented by + users of libthread_db. */ + +/* Addresses. */ +typedef void *psaddr_t; + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; + +/* We don't have any differences between processes and threads, + therefore have only one PID type. */ +typedef __pid_t lwpid_t; + +/* Process status and info. In the end we do provide typedefs for them. */ +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +__END_DECLS + +#endif /* sys/procfs.h */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h new file mode 100644 index 000000000..acb71a2bc --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/reg.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2001, 2002 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 _SYS_REG_H +#define _SYS_REG_H 1 +#include <bits/wordsize.h> + + +#if __WORDSIZE == 64 +/* Index into an array of 8 byte longs returned from ptrace for + location of the users' stored general purpose registers. */ + +# define R15 0 +# define R14 1 +# define R13 2 +# define R12 3 +# define RBP 4 +# define RBX 5 +# define R11 6 +# define R10 7 +# define R9 8 +# define R8 9 +# define RAX 10 +# define RCX 11 +# define RDX 12 +# define RSI 13 +# define RDI 14 +# define ORIG_RAX 15 +# define RIP 16 +# define CS 17 +# define EFLAGS 18 +# define RSP 19 +# define SS 20 +# define FS_BASE 21 +# define GS_BASE 22 +# define DS 23 +# define ES 24 +# define FS 25 +# define GS 26 +#else + +/* Index into an array of 4 byte integers returned from ptrace for + * location of the users' stored general purpose registers. */ + +# define EBX 0 +# define ECX 1 +# define EDX 2 +# define ESI 3 +# define EDI 4 +# define EBP 5 +# define EAX 6 +# define DS 7 +# define ES 8 +# define FS 9 +# define GS 10 +# define ORIG_EAX 11 +# define EIP 12 +# define CS 13 +# define EFL 14 +# define UESP 15 +# define SS 16 +#endif + +#endif diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h new file mode 100644 index 000000000..b59cd292f --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/ucontext.h @@ -0,0 +1,248 @@ +/* Copyright (C) 2001, 2002 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 _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> +#include <signal.h> +#include <bits/wordsize.h> + +/* We need the signal context definitions even if they are not used + included in <signal.h>. */ +#include <bits/sigcontext.h> + +#if __WORDSIZE == 64 + +/* Type for general register. */ +typedef long int greg_t; + +/* Number of general registers. */ +#define NGREG 23 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +#ifdef __USE_GNU +/* Number of each register in the `gregset_t' array. */ +enum +{ + REG_R8 = 0, +# define REG_R8 REG_R8 + REG_R9, +# define REG_R9 REG_R9 + REG_R10, +# define REG_R10 REG_R10 + REG_R11, +# define REG_R11 REG_R11 + REG_R12, +# define REG_R12 REG_R12 + REG_R13, +# define REG_R13 REG_R13 + REG_R14, +# define REG_R14 REG_R14 + REG_R15, +# define REG_R15 REG_R15 + REG_RDI, +# define REG_RDI REG_RDI + REG_RSI, +# define REG_RSI REG_RSI + REG_RBP, +# define REG_RBP REG_RBP + REG_RBX, +# define REG_RBX REG_RBX + REG_RDX, +# define REG_RDX REG_RDX + REG_RAX, +# define REG_RAX REG_RAX + REG_RCX, +# define REG_RCX REG_RCX + REG_RSP, +# define REG_RSP REG_RSP + REG_RIP, +# define REG_RIP REG_RIP + REG_EFL, +# define REG_EFL REG_EFL + REG_CSGSFS, /* Actually short cs, gs, fs, __pad0. */ +# define REG_CSGSFS REG_CSGSFS + REG_ERR, +# define REG_ERR REG_ERR + REG_TRAPNO, +# define REG_TRAPNO REG_TRAPNO + REG_OLDMASK, +# define REG_OLDMASK REG_OLDMASK + REG_CR2 +# define REG_CR2 REG_CR2 +}; +#endif + +struct _libc_fpxreg +{ + unsigned short int significand[4]; + unsigned short int exponent; + unsigned short int padding[3]; +}; + +struct _libc_xmmreg +{ + __uint32_t element[4]; +}; + +struct _libc_fpstate +{ + /* 64-bit FXSAVE format. */ + __uint16_t cwd; + __uint16_t swd; + __uint16_t ftw; + __uint16_t fop; + __uint64_t rip; + __uint64_t rdp; + __uint32_t mxcsr; + __uint32_t mxcr_mask; + struct _libc_fpxreg _st[8]; + struct _libc_xmmreg _xmm[16]; + __uint32_t padding[24]; +}; + +/* Structure to describe FPU registers. */ +typedef struct _libc_fpstate *fpregset_t; + +/* Context to describe whole processor state. */ +typedef struct + { + gregset_t gregs; + /* Note that fpregs is a pointer. */ + fpregset_t fpregs; + unsigned long __reserved1 [8]; +} mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + struct _libc_fpstate __fpregs_mem; + } ucontext_t; + +#else /* __WORDSIZE == 32 */ + +/* Type for general register. */ +typedef int greg_t; + +/* Number of general registers. */ +#define NGREG 19 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +#ifdef __USE_GNU +/* Number of each register is the `gregset_t' array. */ +enum +{ + REG_GS = 0, +# define REG_GS REG_GS + REG_FS, +# define REG_FS REG_FS + REG_ES, +# define REG_ES REG_ES + REG_DS, +# define REG_DS REG_DS + REG_EDI, +# define REG_EDI REG_EDI + REG_ESI, +# define REG_ESI REG_ESI + REG_EBP, +# define REG_EBP REG_EBP + REG_ESP, +# define REG_ESP REG_ESP + REG_EBX, +# define REG_EBX REG_EBX + REG_EDX, +# define REG_EDX REG_EDX + REG_ECX, +# define REG_ECX REG_ECX + REG_EAX, +# define REG_EAX REG_EAX + REG_TRAPNO, +# define REG_TRAPNO REG_TRAPNO + REG_ERR, +# define REG_ERR REG_ERR + REG_EIP, +# define REG_EIP REG_EIP + REG_CS, +# define REG_CS REG_CS + REG_EFL, +# define REG_EFL REG_EFL + REG_UESP, +# define REG_UESP REG_UESP + REG_SS +# define REG_SS REG_SS +}; +#endif + +/* Definitions taken from the kernel headers. */ +struct _libc_fpreg +{ + unsigned short int significand[4]; + unsigned short int exponent; +}; + +struct _libc_fpstate +{ + unsigned long int cw; + unsigned long int sw; + unsigned long int tag; + unsigned long int ipoff; + unsigned long int cssel; + unsigned long int dataoff; + unsigned long int datasel; + struct _libc_fpreg _st[8]; + unsigned long int status; +}; + +/* Structure to describe FPU registers. */ +typedef struct _libc_fpstate *fpregset_t; + +/* Context to describe whole processor state. */ +typedef struct + { + gregset_t gregs; + /* Due to Linux's history we have to use a pointer here. The SysV/i386 + ABI requires a struct with the values. */ + fpregset_t fpregs; + unsigned long int oldmask; + unsigned long int cr2; + } mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + struct _libc_fpstate __fpregs_mem; + } ucontext_t; + +#endif /* __WORDSIZE == 32 */ + +#endif /* sys/ucontext.h */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h b/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h new file mode 100644 index 000000000..ceadcf478 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sys/user.h @@ -0,0 +1,175 @@ +/* Copyright (C) 2001, 2002, 2004 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 _SYS_USER_H +#define _SYS_USER_H 1 + +/* The whole purpose of this file is for GDB and GDB only. Don't read + too much into it. Don't use it for anything other than GDB unless + you know what you are doing. */ + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 + +struct user_fpregs_struct +{ + __uint16_t cwd; + __uint16_t swd; + __uint16_t ftw; + __uint16_t fop; + __uint64_t rip; + __uint64_t rdp; + __uint32_t mxcsr; + __uint32_t mxcr_mask; + __uint32_t st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + __uint32_t xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ + __uint32_t padding[24]; +}; + +struct user_regs_struct +{ + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long rbp; + unsigned long rbx; + unsigned long r11; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long rax; + unsigned long rcx; + unsigned long rdx; + unsigned long rsi; + unsigned long rdi; + unsigned long orig_rax; + unsigned long rip; + unsigned long cs; + unsigned long eflags; + unsigned long rsp; + unsigned long ss; + unsigned long fs_base; + unsigned long gs_base; + unsigned long ds; + unsigned long es; + unsigned long fs; + unsigned long gs; +}; + +struct user +{ + struct user_regs_struct regs; + int u_fpvalid; + struct user_fpregs_struct i387; + unsigned long int u_tsize; + unsigned long int u_dsize; + unsigned long int u_ssize; + unsigned long start_code; + unsigned long start_stack; + long int signal; + int reserved; + struct user_regs_struct* u_ar0; + struct user_fpregs_struct* u_fpstate; + unsigned long int magic; + char u_comm [32]; + unsigned long int u_debugreg [8]; +}; + +#else +/* These are the 32-bit x86 structures. */ +struct user_fpregs_struct +{ + long int cwd; + long int swd; + long int twd; + long int fip; + long int fcs; + long int foo; + long int fos; + long int st_space [20]; +}; + +struct user_fpxregs_struct +{ + unsigned short int cwd; + unsigned short int swd; + unsigned short int twd; + unsigned short int fop; + long int fip; + long int fcs; + long int foo; + long int fos; + long int mxcsr; + long int reserved; + long int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long int padding[56]; +}; + +struct user_regs_struct +{ + long int ebx; + long int ecx; + long int edx; + long int esi; + long int edi; + long int ebp; + long int eax; + long int xds; + long int xes; + long int xfs; + long int xgs; + long int orig_eax; + long int eip; + long int xcs; + long int eflags; + long int esp; + long int xss; +}; + +struct user +{ + struct user_regs_struct regs; + int u_fpvalid; + struct user_fpregs_struct i387; + unsigned long int u_tsize; + unsigned long int u_dsize; + unsigned long int u_ssize; + unsigned long start_code; + unsigned long start_stack; + long int signal; + int reserved; + struct user_regs_struct* u_ar0; + struct user_fpregs_struct* u_fpstate; + unsigned long int magic; + char u_comm [32]; + int u_debugreg [8]; +}; +#endif /* __WORDSIZE */ + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _SYS_USER_H */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S b/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S new file mode 100644 index 000000000..cf49dbcd1 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/syscall.S @@ -0,0 +1,44 @@ +/* Copyright (C) 2001, 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 <sysdep.h> + +/* Please consult the file sysdeps/unix/sysv/linux/x86-64/sysdep.h for + more information about the value -4095 used below. */ + +/* Usage: long syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6) + We need to do some arg shifting, the syscall_number will be in + rax. */ + + + .text +ENTRY (syscall) + movq %rdi, %rax /* Syscall number -> rax. */ + movq %rsi, %rdi /* shift arg1 - arg5. */ + movq %rdx, %rsi + movq %rcx, %rdx + movq %r8, %r10 + movq %r9, %r8 + movq 8(%rsp),%r9 /* arg6 is on the stack. */ + syscall /* Do the system call. */ + cmpq $-4095, %rax /* Check %rax for error. */ + jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ +L(pseudo_end): + ret /* Return to caller. */ + +PSEUDO_END (syscall) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list new file mode 100644 index 000000000..a9d40446d --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/syscalls.list @@ -0,0 +1,36 @@ +# File name Caller Syscall name # args Strong name Weak names + +arch_prctl EXTRA arch_prctl i:ii __arch_prctl arch_prctl +modify_ldt EXTRA modify_ldt i:ipi __modify_ldt modify_ldt + +# semaphore and shm system calls +msgctl - msgctl i:iip __msgctl msgctl +msgget - msgget i:ii __msgget msgget +msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv +msgsnd - msgsnd Ci:ibni __msgsnd msgsnd +shmat - shmat i:ipi __shmat shmat +shmctl - shmctl i:iip __shmctl shmctl +shmdt - shmdt i:s __shmdt shmdt +shmget - shmget i:iii __shmget shmget +semop - semop i:ipi __semop semop +semtimedop - semtimedop i:ipip semtimedop +semget - semget i:iii __semget semget +semctl - semctl i:iiii __semctl semctl + + +# proper socket implementations: +accept - accept Ci:iBN __libc_accept __accept accept +bind - bind i:ipi __bind bind +connect - connect Ci:ipi __libc_connect __connect_internal __connect connect +getpeername - getpeername i:ipp __getpeername getpeername +getsockname - getsockname i:ipp __getsockname getsockname +getsockopt - getsockopt i:iiiBN __getsockopt getsockopt +listen - listen i:ii __listen listen +recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom +recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg +sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg +sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto +setsockopt - setsockopt i:iiibn __setsockopt setsockopt +shutdown - shutdown i:ii __shutdown shutdown +socket - socket i:iii __socket socket +socketpair - socketpair i:iiif __socketpair socketpair diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c b/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c new file mode 100644 index 000000000..726c5e33a --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysconf.c @@ -0,0 +1,326 @@ +/* Get file-specific information about a file. Linux version. + Copyright (C) 2003, 2004, 2006 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 <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + + +static long int linux_sysconf (int name); + + +static const struct intel_02_cache_info +{ + unsigned int idx; + int name; + long int size; + long int assoc; + long int linesize; +} intel_02_known[] = + { + { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 }, + { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 }, + { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 }, + { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 }, + { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, + { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, + { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, + { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, + { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 }, + { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 }, + { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 }, + { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 }, + { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 }, + { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 }, + { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 }, + { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, + { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 }, + { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 }, + { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 }, + { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 }, + { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 }, + { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 }, + { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 }, + { 0x49, _SC_LEVEL3_CACHE_SIZE, 4194304, 16, 64 }, + { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 }, + { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, + { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 }, + { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 }, + { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 }, + { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 }, + { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, + { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 }, + { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, + { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 }, + { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, + { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 }, + { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, + { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 }, + { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 }, + { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 }, + { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 }, + { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 }, + { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 }, + { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, + { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, + }; +#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known[0])) + + +static int +intel_02_known_compare (const void *p1, const void *p2) +{ + const struct intel_02_cache_info *i1; + const struct intel_02_cache_info *i2; + + i1 = (const struct intel_02_cache_info *) p1; + i2 = (const struct intel_02_cache_info *) p2; + + if (i1->idx == i2->idx) + return 0; + + return i1->idx < i2->idx ? -1 : 1; +} + + +static long int +intel_check_word (int name, unsigned int value, bool *has_level_2, + bool *no_level_2_or_3) +{ + if ((value & 0x80000000) != 0) + /* The register value is reserved. */ + return 0; + + /* Fold the name. The _SC_ constants are always in the order SIZE, + ASSOC, LINESIZE. */ + int folded_name = (_SC_LEVEL1_ICACHE_SIZE + + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3); + + while (value != 0) + { + unsigned int byte = value & 0xff; + + if (byte == 0x40) + { + *no_level_2_or_3 = true; + + if (folded_name == _SC_LEVEL3_CACHE_SIZE) + /* No need to look further. */ + break; + } + else + { + struct intel_02_cache_info *found; + struct intel_02_cache_info search; + + search.idx = byte; + found = bsearch (&search, intel_02_known, nintel_02_known, + sizeof (intel_02_known[0]), intel_02_known_compare); + if (found != NULL) + { + if (found->name == folded_name) + { + unsigned int offset = name - folded_name; + + if (offset == 0) + /* Cache size. */ + return found->size; + if (offset == 1) + return found->assoc; + + assert (offset == 2); + return found->linesize; + } + + if (found->name == _SC_LEVEL2_CACHE_SIZE) + *has_level_2 = true; + } + } + + /* Next byte for the next round. */ + value >>= 8; + } + + /* Nothing found. */ + return 0; +} + + +static long int __attribute__ ((noinline)) +handle_intel (int name, unsigned int maxidx) +{ + assert (maxidx >= 2); + + /* OK, we can use the CPUID instruction to get all info about the + caches. */ + unsigned int cnt = 0; + unsigned int max = 1; + long int result = 0; + bool no_level_2_or_3 = false; + bool has_level_2 = false; + while (cnt++ < max) + { + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "0" (2)); + + /* The low byte of EAX in the first round contain the number of + rounds we have to make. At least one, the one we are already + doing. */ + if (cnt == 1) + { + max = eax & 0xff; + eax &= 0xffffff00; + } + + /* Process the individual registers' value. */ + result = intel_check_word (name, eax, &has_level_2, &no_level_2_or_3); + if (result != 0) + return result; + + result = intel_check_word (name, ebx, &has_level_2, &no_level_2_or_3); + if (result != 0) + return result; + + result = intel_check_word (name, ecx, &has_level_2, &no_level_2_or_3); + if (result != 0) + return result; + + result = intel_check_word (name, edx, &has_level_2, &no_level_2_or_3); + if (result != 0) + return result; + } + + if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE + && no_level_2_or_3) + return -1; + + return 0; +} + + +static long int __attribute__ ((noinline)) +handle_amd (int name) +{ + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "0" (0x80000000)); + + if (name >= _SC_LEVEL3_CACHE_SIZE) + return 0; + + unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE); + if (eax < fn) + return 0; + + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "0" (fn)); + + if (name < _SC_LEVEL1_DCACHE_SIZE) + { + name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE; + ecx = edx; + } + + switch (name) + { + case _SC_LEVEL1_DCACHE_SIZE: + return (ecx >> 14) & 0x3fc00; + case _SC_LEVEL1_DCACHE_ASSOC: + ecx >>= 16; + if ((ecx & 0xff) == 0xff) + /* Fully associative. */ + return (ecx << 2) & 0x3fc00; + return ecx & 0xff; + case _SC_LEVEL1_DCACHE_LINESIZE: + return ecx & 0xff; + case _SC_LEVEL2_CACHE_SIZE: + return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00; + case _SC_LEVEL2_CACHE_ASSOC: + ecx >>= 12; + switch (ecx & 0xf) + { + case 0: + case 1: + case 2: + case 4: + return ecx & 0xf; + case 6: + return 8; + case 8: + return 16; + case 0xf: + return (ecx << 6) & 0x3fffc00; + default: + return 0; + } + case _SC_LEVEL2_CACHE_LINESIZE: + return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff; + default: + assert (! "cannot happen"); + } + return -1; +} + + +/* Get the value of the system variable NAME. */ +long int +__sysconf (int name) +{ + /* We only handle the cache information here (for now). */ + if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE) + return linux_sysconf (name); + + /* Find out what brand of processor. */ + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "0" (0)); + + /* This spells out "GenuineIntel". */ + if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) + return handle_intel (name, eax); + + /* This spells out "AuthenticAMD". */ + if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) + return handle_amd (name); + + // XXX Fill in more vendors. + + /* CPU not known, we have no information. */ + return 0; +} + +/* Now the generic Linux version. */ +#undef __sysconf +#define __sysconf static linux_sysconf +#include "../sysconf.c" diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S new file mode 100644 index 000000000..5b72cef20 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.S @@ -0,0 +1,41 @@ +/* Copyright (C) 2001, 2002 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 <sysdep.h> + +/* The following code is only used in the shared library when we + compile the reentrant version. Otherwise each system call defines + each own version. */ + +#ifndef PIC + +/* The syscall stubs jump here when they detect an error. + The code for Linux is almost identical to the canonical Unix + code, except that the error number in %rax is negated. */ + +#undef CALL_MCOUNT +#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %rax. */ + + .text +ENTRY (__syscall_error) + negq %rax + +#define __syscall_error __syscall_error_1 +#include <sysdeps/unix/x86_64/sysdep.S> + +#endif /* !PIC */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h new file mode 100644 index 000000000..5dfffca45 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -0,0 +1,341 @@ +/* Copyright (C) 2001, 2002, 2003, 2004, 2005 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 <sysdeps/unix/x86_64/sysdep.h> +#include <bp-sym.h> +#include <bp-asm.h> +#include <tls.h> + +#ifdef IS_IN_rtld +# include <dl-sysdep.h> /* 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 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); \ + PUSH_ERRNO_LOCATION_RETURN; \ + call BP_SYM (__errno_location)@PLT; \ + POP_ERRNO_LOCATION_RETURN; \ + 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 + additionally clobered: r12-r15,rbx,rbp + 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 + +#else /* !__ASSEMBLER__ */ +/* Define a macro which expands inline into the wrapper code for a system + call. */ +#undef INLINE_SYSCALL +#define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + unsigned long resultvar = INTERNAL_SYSCALL (name, , nr, args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \ + resultvar = (unsigned long) -1; \ + } \ + (long) resultvar; }) + +#undef INTERNAL_SYSCALL_DECL +#define INTERNAL_SYSCALL_DECL(err) do { } while (0) + +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + unsigned long resultvar; \ + LOAD_ARGS_##nr (args) \ + LOAD_REGS_##nr \ + asm volatile ( \ + "syscall\n\t" \ + : "=a" (resultvar) \ + : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ + (long) resultvar; }) +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) + +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val, err) \ + ((unsigned long) (val) >= -4095L) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) + +#define LOAD_ARGS_0() +#define LOAD_REGS_0 +#define ASM_ARGS_0 + +#define LOAD_ARGS_1(a1) \ + long int __arg1 = (long) (a1); \ + LOAD_ARGS_0 () +#define LOAD_REGS_1 \ + register long int _a1 asm ("rdi") = __arg1; \ + LOAD_REGS_0 +#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1) + +#define LOAD_ARGS_2(a1, a2) \ + long int __arg2 = (long) (a2); \ + LOAD_ARGS_1 (a1) +#define LOAD_REGS_2 \ + register long int _a2 asm ("rsi") = __arg2; \ + LOAD_REGS_1 +#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2) + +#define LOAD_ARGS_3(a1, a2, a3) \ + long int __arg3 = (long) (a3); \ + LOAD_ARGS_2 (a1, a2) +#define LOAD_REGS_3 \ + register long int _a3 asm ("rdx") = __arg3; \ + LOAD_REGS_2 +#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3) + +#define LOAD_ARGS_4(a1, a2, a3, a4) \ + long int __arg4 = (long) (a4); \ + LOAD_ARGS_3 (a1, a2, a3) +#define LOAD_REGS_4 \ + register long int _a4 asm ("r10") = __arg4; \ + LOAD_REGS_3 +#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4) + +#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \ + long int __arg5 = (long) (a5); \ + LOAD_ARGS_4 (a1, a2, a3, a4) +#define LOAD_REGS_5 \ + register long int _a5 asm ("r8") = __arg5; \ + LOAD_REGS_4 +#define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5) + +#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \ + long int __arg6 = (long) (a6); \ + LOAD_ARGS_5 (a1, a2, a3, a4, a5) +#define LOAD_REGS_6 \ + register long int _a6 asm ("r9") = __arg6; \ + LOAD_REGS_5 +#define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6) + +#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 +# define PTR_DEMANGLE(reg) PTR_MANGLE (reg) +# else +# define PTR_MANGLE(reg) asm ("xorq __pointer_chk_guard_local(%%rip), %0"\ + : "=r" (reg) : "0" (reg)) +# define PTR_DEMANGLE(reg) PTR_MANGLE (reg) +# endif +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg +# define PTR_DEMANGLE(reg) PTR_MANGLE (reg) +# else +# define PTR_MANGLE(var) asm ("xorq %%fs:%c2, %0" \ + : "=r" (var) \ + : "0" (var), \ + "i" (offsetof (tcbhead_t, \ + pointer_guard))) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + +#endif /* linux/x86_64/sysdep.h */ diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/time.S b/libc/sysdeps/unix/sysv/linux/x86_64/time.S new file mode 100644 index 000000000..e3f326876 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/time.S @@ -0,0 +1,42 @@ +/* Copyright (C) 2001,02, 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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* For the calculation see asm/vsyscall.h. */ +#define VSYSCALL_ADDR_vtime 0xffffffffff600400 + + +/* Return the current time as a `time_t' and also put it in *T if T is + not NULL. Time is represented as seconds from Jan 1 00:00:00 1970. */ + +ENTRY (time) + /* Align stack. */ + sub $0x8, %rsp + cfi_adjust_cfa_offset(8) + + movq $VSYSCALL_ADDR_vtime, %rax + callq *%rax + + add $0x8, %rsp + cfi_adjust_cfa_offset(-8) + ret +PSEUDO_END_NOERRNO(time) +libc_hidden_def (time) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym new file mode 100644 index 000000000..b3cfe9aa4 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym @@ -0,0 +1,34 @@ +#include <stddef.h> +#include <signal.h> +#include <sys/ucontext.h> + +-- + +SIG_BLOCK +SIG_SETMASK + +_NSIG8 (_NSIG / 8) + +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) +#define mreg(reg) mcontext (gregs[REG_##reg]) + +oRBP mreg (RBP) +oRSP mreg (RSP) +oRBX mreg (RBX) +oR8 mreg (R8) +oR9 mreg (R9) +oR12 mreg (R12) +oR13 mreg (R13) +oR14 mreg (R14) +oR15 mreg (R15) +oRDI mreg (RDI) +oRSI mreg (RSI) +oRDX mreg (RDX) +oRAX mreg (RAX) +oRCX mreg (RCX) +oRIP mreg (RIP) +oFPREGS mcontext (fpregs) +oSIGMASK ucontext (uc_sigmask) +oFPREGSMEM ucontext (__fpregs_mem) +oMXCSR ucontext (__fpregs_mem.mxcsr) diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/umount.c b/libc/sysdeps/unix/sysv/linux/x86_64/umount.c new file mode 100644 index 000000000..a17c5c579 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/umount.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000. + + 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. */ + +/* Since we don't have an oldumount system call, do what the kernel + does down here. */ + +extern long int __umount2 (const char *name, int flags); + +long int +__umount (const char *name) +{ + return __umount2 (name, 0); +} + +weak_alias (__umount, umount); diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S b/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S new file mode 100644 index 000000000..4bad38892 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -0,0 +1,61 @@ +/* Copyright (C) 2001, 2002, 2004 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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) + + /* Pop the return PC value into RDI. We need a register that + is preserved by the syscall and that we're allowed to destroy. */ + popq %rdi + cfi_adjust_cfa_offset(-8) + +#ifdef SAVE_PID + SAVE_PID +#endif + + /* Stuff the syscall number in RAX and enter into the kernel. */ + movl $SYS_ify (vfork), %eax + syscall + + /* Push back the return PC. */ + pushq %rdi + cfi_adjust_cfa_offset(8) + +#ifdef RESTORE_PID + RESTORE_PID +#endif + + cmpl $-4095, %eax + jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */ + + /* Normal return. */ +.Lpseudo_end: + ret + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) |