diff options
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/Versions | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/bits/statvfs.h | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/check_pf.c | 42 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/clone.S | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/getgroups.c | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/sigaction.c | 14 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ifaddrs.c | 75 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/internal_statvfs.c | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/posix_madvise.c | 38 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sh/bits/shm.h | 101 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sh/sys/io.h | 48 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sys/epoll.h | 20 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/syscalls.list | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/clone.S | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/sigaction.c | 104 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym | 3 |
17 files changed, 305 insertions, 172 deletions
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 7c015b1d62..137b44c2b8 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -126,6 +126,9 @@ libc { GLIBC_2.5 { splice; sync_file_range; tee; vmsplice; } + GLIBC_2.6 { + epoll_pwait; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/bits/statvfs.h b/sysdeps/unix/sysv/linux/bits/statvfs.h index cca0871ac0..84717c3d96 100644 --- a/sysdeps/unix/sysv/linux/bits/statvfs.h +++ b/sysdeps/unix/sysv/linux/bits/statvfs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000,2001,2002,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 @@ -101,7 +101,9 @@ enum # define ST_IMMUTABLE ST_IMMUTABLE ST_NOATIME = 1024, /* Do not update access times. */ # define ST_NOATIME ST_NOATIME - ST_NODIRATIME = 2048 /* Do not update directory access times. */ + ST_NODIRATIME = 2048, /* Do not update directory access times. */ # define ST_NODIRATIME ST_NODIRATIME + ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */ +# define ST_RELATIME ST_RELATIME #endif /* Use GNU. */ }; diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index 46161a806a..13ccd7acb4 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -1,5 +1,5 @@ /* Determine protocol families for which interfaces exist. Linux version. - Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 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 @@ -71,38 +71,17 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, memset (&nladdr, '\0', sizeof (nladdr)); nladdr.nl_family = AF_NETLINK; -#ifdef PAGE_SIZE - /* Help the compiler optimize out the malloc call if PAGE_SIZE - is constant and smaller or equal to PTHREAD_STACK_MIN/4. */ - const size_t buf_size = PAGE_SIZE; -#else - const size_t buf_size = __getpagesize (); -#endif - bool use_malloc = false; - char *buf; - - if (__libc_use_alloca (buf_size)) - buf = alloca (buf_size); - else - { - buf = malloc (buf_size); - if (buf != NULL) - use_malloc = true; - else - goto out_fail; - } - - struct iovec iov = { buf, buf_size }; - if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0, (struct sockaddr *) &nladdr, sizeof (nladdr))) < 0) - goto out_fail; + return -1; *seen_ipv4 = false; *seen_ipv6 = false; bool done = false; + char buf[4096]; + struct iovec iov = { buf, sizeof (buf) }; struct in6ailist { struct in6addrinfo info; @@ -122,10 +101,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0)); if (read_len < 0) - goto out_fail; + return -1; if (msg.msg_flags & MSG_TRUNC) - goto out_fail; + return -1; struct nlmsghdr *nlmh; for (nlmh = (struct nlmsghdr *) buf; @@ -207,7 +186,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, { *in6ai = malloc (in6ailistlen * sizeof (**in6ai)); if (*in6ai == NULL) - goto out_fail; + return -1; *in6ailen = in6ailistlen; @@ -219,14 +198,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, while (in6ailist != NULL); } - if (use_malloc) - free (buf); return 0; - -out_fail: - if (use_malloc) - free (buf); - return -1; } diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index 54524ec120..f73a4b5195 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -120,6 +120,9 @@ L(pseudo_end): ret L(thread_start): + cfi_startproc; + /* Clearing frame pointer is insufficient, use CFI. */ + cfi_undefined (eip); /* Note: %esi is zero. */ movl %esi,%ebp /* terminate the stack frame */ #ifdef RESET_PID @@ -152,6 +155,7 @@ L(nomoregetpid): jmp L(haspid) .previous #endif + cfi_endproc; cfi_startproc PSEUDO_END (BP_SYM (__clone)) diff --git a/sysdeps/unix/sysv/linux/i386/getgroups.c b/sysdeps/unix/sysv/linux/i386/getgroups.c index b7a0a4efd4..f69baf943b 100644 --- a/sysdeps/unix/sysv/linux/i386/getgroups.c +++ b/sysdeps/unix/sysv/linux/i386/getgroups.c @@ -52,8 +52,6 @@ __getgroups (int n, gid_t *groups) } else { - int i, ngids; - __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))]; # ifdef __NR_getgroups32 if (__libc_missing_32bit_uids <= 0) { @@ -69,6 +67,9 @@ __getgroups (int n, gid_t *groups) } # endif /* __NR_getgroups32 */ + int i, ngids; + __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))]; + ngids = INLINE_SYSCALL (getgroups, 2, n, CHECK_N (kernel_groups, n)); if (n != 0 && ngids > 0) for (i = 0; i < ngids; i++) diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index 299574dac4..b5c1b98573 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -1,5 +1,5 @@ /* POSIX.1 `sigaction' call for Linux/i386. - Copyright (C) 1991,1995-2000,2002-2004,2005 Free Software Foundation, Inc. + Copyright (C) 1991,1995-2000,2002-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 @@ -46,18 +46,10 @@ int __libc_missing_rt_sigs; /* 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 -# ifdef __NR_rt_sigaction +#ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -# endif -extern void restore (void) asm ("__restore") attribute_hidden; -#else -# ifdef __NR_rt_sigaction -static void restore_rt (void) asm ("__restore_rt"); -# endif -static void restore (void) asm ("__restore"); #endif +extern void restore (void) asm ("__restore") attribute_hidden; /* If ACT is not NULL, change the action for SIG to *ACT. diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index 02e6935538..82495de03e 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -1,5 +1,5 @@ /* getifaddrs -- get names and addresses of all network interfaces - Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 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 @@ -122,36 +122,36 @@ int __netlink_request (struct netlink_handle *h, int type) { struct netlink_res *nlm_next; + struct netlink_res **new_nlm_list; + static volatile size_t buf_size = 4096; + char *buf; struct sockaddr_nl nladdr; struct nlmsghdr *nlmh; ssize_t read_len; bool done = false; - -#ifdef PAGE_SIZE - /* Help the compiler optimize out the malloc call if PAGE_SIZE - is constant and smaller or equal to PTHREAD_STACK_MIN/4. */ - const size_t buf_size = PAGE_SIZE; -#else - const size_t buf_size = __getpagesize (); -#endif bool use_malloc = false; - char *buf; - if (__libc_use_alloca (buf_size)) - buf = alloca (buf_size); + if (__netlink_sendreq (h, type) < 0) + return -1; + + size_t this_buf_size = buf_size; + if (__libc_use_alloca (this_buf_size)) + buf = alloca (this_buf_size); else { - buf = malloc (buf_size); + buf = malloc (this_buf_size); if (buf != NULL) use_malloc = true; else goto out_fail; } - struct iovec iov = { buf, buf_size }; + struct iovec iov = { buf, this_buf_size }; - if (__netlink_sendreq (h, type) < 0) - goto out_fail; + if (h->nlm_list != NULL) + new_nlm_list = &h->end_ptr->next; + else + new_nlm_list = &h->nlm_list; while (! done) { @@ -171,7 +171,48 @@ __netlink_request (struct netlink_handle *h, int type) continue; if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0)) - goto out_fail; + { + if (this_buf_size >= SIZE_MAX / 2) + goto out_fail; + + nlm_next = *new_nlm_list; + while (nlm_next != NULL) + { + struct netlink_res *tmpptr; + + tmpptr = nlm_next->next; + free (nlm_next); + nlm_next = tmpptr; + } + *new_nlm_list = NULL; + + if (__libc_use_alloca (2 * this_buf_size)) + buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size); + else + { + this_buf_size *= 2; + + char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size); + if (new_buf == NULL) + goto out_fail; + new_buf = buf; + + use_malloc = true; + } + buf_size = this_buf_size; + + iov.iov_base = buf; + iov.iov_len = this_buf_size; + + /* Increase sequence number, so that we can distinguish + between old and new request messages. */ + h->seq++; + + if (__netlink_sendreq (h, type) < 0) + goto out_fail; + + continue; + } size_t count = 0; size_t remaining_len = read_len; diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c index 73317ecafd..28c1cb691f 100644 --- a/sysdeps/unix/sysv/linux/internal_statvfs.c +++ b/sysdeps/unix/sysv/linux/internal_statvfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -156,6 +156,8 @@ __statvfs_getflags (const char *name, int fstype, struct stat64 *st) result |= ST_NOATIME; else if (strcmp (opt, "nodiratime") == 0) result |= ST_NODIRATIME; + else if (strcmp (opt, "relatime") == 0) + result |= ST_RELATIME; /* We can stop looking for more entries. */ success = true; diff --git a/sysdeps/unix/sysv/linux/posix_madvise.c b/sysdeps/unix/sysv/linux/posix_madvise.c deleted file mode 100644 index 880b17ef31..0000000000 --- a/sysdeps/unix/sysv/linux/posix_madvise.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <sysdep.h> -#include <sys/mman.h> - - -int -posix_madvise (void *addr, size_t len, int advice) -{ - /* We have one problem: the kernel's MADV_DONTNEED does not - correspond to POSIX's POSIX_MADV_DONTNEED. The former simply - discards changes made to the memory without writing it back to - disk, if this would be necessary. The POSIX behavior does not - allow this. There is no functionality mapping the POSIX behavior - so far so we ignore that advice for now. */ - if (advice == POSIX_MADV_DONTNEED) - return 0; - - INTERNAL_SYSCALL_DECL (err); - int result = INTERNAL_SYSCALL (madvise, err, 3, addr, len, advice); - return INTERNAL_SYSCALL_ERRNO (result, err); -} diff --git a/sysdeps/unix/sysv/linux/sh/bits/shm.h b/sysdeps/unix/sysv/linux/sh/bits/shm.h new file mode 100644 index 0000000000..189179394b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/bits/shm.h @@ -0,0 +1,101 @@ +/* Copyright (C) 1995,1996,1997,2000,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 _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 0x4000 + +/* 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() */ + unsigned long int __unused1; + __time_t shm_dtime; /* time of last shmdt() */ + unsigned long int __unused2; + __time_t shm_ctime; /* time of last change by shmctl() */ + unsigned long int __unused3; + __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/sysdeps/unix/sysv/linux/sh/sys/io.h b/sysdeps/unix/sysv/linux/sh/sys/io.h deleted file mode 100644 index 6fdc44ff89..0000000000 --- a/sysdeps/unix/sysv/linux/sh/sys/io.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 1996, 1998, 1999, 2000 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. */ -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 is nonzero, - permission to access any I/O port is granted. This call requires - root privileges. */ -extern int iopl (int __level) __THROW; - -/* The functions that actually perform reads and writes. */ -extern unsigned char inb (unsigned long int port) __THROW; -extern unsigned short int inw (unsigned long int port) __THROW; -extern unsigned long int inl (unsigned long int port) __THROW; - -extern void outb (unsigned char value, unsigned long int port) __THROW; -extern void outw (unsigned short value, unsigned long int port) __THROW; -extern void outl (unsigned long value, unsigned long int port) __THROW; - -__END_DECLS - -#endif /* _SYS_IO_H */ diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h index 68f173a04d..d8901f7d53 100644 --- a/sysdeps/unix/sysv/linux/sys/epoll.h +++ b/sysdeps/unix/sysv/linux/sys/epoll.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* 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 @@ -22,6 +22,14 @@ #include <stdint.h> #include <sys/types.h> +/* Get __sigset_t. */ +#include <bits/sigset.h> + +#ifndef __sigset_t_defined +# define __sigset_t_defined +typedef __sigset_t sigset_t; +#endif + enum EPOLL_EVENTS { @@ -105,6 +113,16 @@ extern int epoll_ctl (int __epfd, int __op, int __fd, extern int epoll_wait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout); + +/* Same as epoll_wait, but the thread's signal mask is temporarily + and atomically replaced with the one provided as parameter. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern int epoll_pwait (int __epfd, struct epoll_event *__events, + int __maxevents, int __timeout, + __const __sigset_t *__ss); + __END_DECLS #endif /* sys/epoll.h */ diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index e16110480f..5776673733 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -10,7 +10,8 @@ delete_module EXTRA delete_module 3 delete_module epoll_create EXTRA epoll_create i:i epoll_create epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait -fdatasync - fdatasync Ci:i fdatasync +epoll_pwait EXTRA epoll_pwait Ci:ipiipi epoll_pwait +fdatasync - fdatasync i:i fdatasync flock - flock i:ii __flock flock fork - fork i: __libc_fork __fork fork get_kernel_syms EXTRA get_kernel_syms i:p get_kernel_syms @@ -31,6 +32,7 @@ ioperm - ioperm i:iii ioperm iopl - iopl i:i iopl klogctl EXTRA syslog i:isi klogctl lchown - lchown i:sii __lchown lchown +posix_madvise - madvise Vi:pii posix_madvise madvise - madvise i:pii madvise mincore - mincore i:anV mincore mlock - mlock i:bn mlock diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile index 0f20367236..bdad5063df 100644 --- a/sysdeps/unix/sysv/linux/x86_64/Makefile +++ b/sysdeps/unix/sysv/linux/x86_64/Makefile @@ -10,6 +10,6 @@ ifeq ($(subdir),stdlib) sysdep_routines += __start_context endif -ifeq ($(subdir),stdlib) +ifeq ($(subdir),csu) gen-as-const-headers += ucontext_i.sym endif diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index 8a12b09035..db42f209c9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -89,6 +89,9 @@ L(pseudo_end): ret L(thread_start): + cfi_startproc; + /* Clearing frame pointer is insufficient, use CFI. */ + cfi_undefined (rip); /* Clear the frame pointer. The ABI suggests this be done, to mark the outermost frame obviously. */ xorl %ebp, %ebp @@ -113,6 +116,7 @@ L(thread_start): /* Call exit with return value from function call. */ movq %rax, %rdi call HIDDEN_JUMPTARGET (_exit) + cfi_endproc; cfi_startproc; PSEUDO_END (BP_SYM (__clone)) diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index d6f4558cef..ab10123858 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -1,5 +1,5 @@ /* POSIX.1 `sigaction' call for Linux/x86-64. - Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 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 @@ -33,17 +33,14 @@ translate it here. */ #include <kernel_sigaction.h> +#include "ucontext_i.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. @@ -95,18 +92,95 @@ weak_alias (__libc_sigaction, sigaction) 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. */ + appropriate GDB maintainer. + + The unwind information starts a byte before __restore_rt, so that + it is found when unwinding, to get an address the unwinder assumes + will be in the middle of a call instruction. See the Linux kernel + (the i386 vsyscall, in particular) for an explanation of the complex + unwind information used here in order to get the traditional CFA. + We do not restore cs - it's only stored as two bytes here so that's + a bit tricky. We don't use the gas cfi directives, so that we can + reliably add .cfi_signal_frame. */ + +#define do_cfa_expr \ + " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ + " .uleb128 2f-1f\n" /* length */ \ + "1: .byte 0x77\n" /* DW_OP_breg7 */ \ + " .sleb128 " CFI_STRINGIFY (oRSP) "\n" \ + " .byte 0x06\n" /* DW_OP_deref */ \ + "2:" + +#define do_expr(regno, offset) \ + " .byte 0x10\n" /* DW_CFA_expression */ \ + " .uleb128 " CFI_STRINGIFY (regno) "\n" \ + " .uleb128 2f-1f\n" /* length */ \ + "1: .byte 0x77\n" /* DW_OP_breg7 */ \ + " .sleb128 " CFI_STRINGIFY (offset) "\n" \ + "2:" #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" \ +asm \ + ( \ + /* `nop' for debuggers assuming `call' should not disalign the code. */ \ + " nop\n" \ + ".align 16\n" \ + ".LSTART_" #name ":\n" \ + " .type __" #name ",@function\n" \ + "__" #name ":\n" \ + " movq $" #syscall ", %rax\n" \ + " syscall\n" \ + ".LEND_" #name ":\n" \ + ".section .eh_frame,\"a\",@progbits\n" \ + ".LSTARTFRAME_" #name ":\n" \ + " .long .LENDCIE_" #name "-.LSTARTCIE_" #name "\n" \ + ".LSTARTCIE_" #name ":\n" \ + " .long 0\n" /* CIE ID */ \ + " .byte 1\n" /* Version number */ \ + " .string \"zRS\"\n" /* NUL-terminated augmentation string */ \ + " .uleb128 1\n" /* Code alignment factor */ \ + " .sleb128 -8\n" /* Data alignment factor */ \ + " .uleb128 16\n" /* Return address register column (rip) */ \ + /* Augmentation value length */ \ + " .uleb128 .LENDAUGMNT_" #name "-.LSTARTAUGMNT_" #name "\n" \ + ".LSTARTAUGMNT_" #name ":\n" \ + " .byte 0x1b\n" /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ \ + ".LENDAUGMNT_" #name ":\n" \ + " .align 8\n" \ + ".LENDCIE_" #name ":\n" \ + " .long .LENDFDE_" #name "-.LSTARTFDE_" #name "\n" /* FDE len */ \ + ".LSTARTFDE_" #name ":\n" \ + " .long .LSTARTFDE_" #name "-.LSTARTFRAME_" #name "\n" /* CIE */ \ + /* `LSTART_' is subtracted 1 as debuggers assume a `call' here. */ \ + " .long (.LSTART_" #name "-1)-.\n" /* PC-relative start addr. */ \ + " .long .LEND_" #name "-(.LSTART_" #name "-1)\n" \ + " .uleb128 0\n" /* FDE augmentation length */ \ + do_cfa_expr \ + do_expr (8 /* r8 */, oR8) \ + do_expr (9 /* r9 */, oR9) \ + do_expr (10 /* r10 */, oR10) \ + do_expr (11 /* r11 */, oR11) \ + do_expr (12 /* r12 */, oR12) \ + do_expr (13 /* r13 */, oR13) \ + do_expr (14 /* r14 */, oR14) \ + do_expr (15 /* r15 */, oR15) \ + do_expr (5 /* rdi */, oRDI) \ + do_expr (4 /* rsi */, oRSI) \ + do_expr (6 /* rbp */, oRBP) \ + do_expr (3 /* rbx */, oRBX) \ + do_expr (1 /* rdx */, oRDX) \ + do_expr (0 /* rax */, oRAX) \ + do_expr (2 /* rcx */, oRCX) \ + do_expr (7 /* rsp */, oRSP) \ + do_expr (16 /* rip */, oRIP) \ + /* libgcc-4.1.1 has only `DWARF_FRAME_REGISTERS == 17'. */ \ + /* do_expr (49 |* rflags *|, oEFL) */ \ + /* `cs'/`ds'/`fs' are unaligned and a different size. */ \ + /* gas: Error: register save offset not a multiple of 8 */ \ + " .align 8\n" \ + ".LENDFDE_" #name ":\n" \ + " .previous\n" \ ); /* The return code for realtime-signals. */ RESTORE (restore_rt, __NR_rt_sigreturn) diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym index b3cfe9aa4c..af3e0e544b 100644 --- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym @@ -18,6 +18,8 @@ oRSP mreg (RSP) oRBX mreg (RBX) oR8 mreg (R8) oR9 mreg (R9) +oR10 mreg (R10) +oR11 mreg (R11) oR12 mreg (R12) oR13 mreg (R13) oR14 mreg (R14) @@ -28,6 +30,7 @@ oRDX mreg (RDX) oRAX mreg (RAX) oRCX mreg (RCX) oRIP mreg (RIP) +oEFL mreg (EFL) oFPREGS mcontext (fpregs) oSIGMASK ucontext (uc_sigmask) oFPREGSMEM ucontext (__fpregs_mem) |