summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/bits/statvfs.h6
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c42
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/i386/getgroups.c5
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c14
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c75
-rw-r--r--sysdeps/unix/sysv/linux/internal_statvfs.c4
-rw-r--r--sysdeps/unix/sysv/linux/posix_madvise.c38
-rw-r--r--sysdeps/unix/sysv/linux/sh/bits/shm.h101
-rw-r--r--sysdeps/unix/sysv/linux/sh/sys/io.h48
-rw-r--r--sysdeps/unix/sysv/linux/sys/epoll.h20
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sigaction.c104
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym3
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)