summaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/clock_settime.c6
-rw-r--r--sysdeps/unix/sysv/linux/clock_gettime.c10
-rw-r--r--sysdeps/unix/sysv/linux/dl-osinfo.h1
-rw-r--r--sysdeps/unix/sysv/linux/dl-vdso.c (renamed from sysdeps/unix/sysv/linux/powerpc/dl-vdso.c)15
-rw-r--r--sysdeps/unix/sysv/linux/dl-vdso.h49
-rw-r--r--sysdeps/unix/sysv/linux/fstatfs64.c4
-rw-r--r--sysdeps/unix/sysv/linux/fxstatat.c3
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h4
-rw-r--r--sysdeps/unix/sysv/linux/if_index.c3
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c1
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h50
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/libc-start.c65
-rw-r--r--sysdeps/unix/sysv/linux/ppoll.c4
-rw-r--r--sysdeps/unix/sysv/linux/pselect.c4
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/mmap.S3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S3
-rw-r--r--sysdeps/unix/sysv/linux/shm_open.c2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c2
-rw-r--r--sysdeps/unix/sysv/linux/statfs64.c3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h (renamed from sysdeps/unix/sysv/linux/powerpc/dl-vdso.h)24
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/gettimeofday.S7
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/libc-start.c49
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h210
-rw-r--r--sysdeps/unix/sysv/linux/xstatconv.c4
28 files changed, 371 insertions, 166 deletions
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index a93be6349b..f3f62cf990 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004, 2006, 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
@@ -23,7 +23,7 @@
#include <ldsodefs.h>
-#if HP_TIMING_AVAIL
+#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
/* Clock frequency of the processor. We make it a 64-bit variable
because some jokers are already playing with processors with more
than 4GHz. */
@@ -33,10 +33,8 @@ static hp_timing_t freq;
/* This function is defined in the thread library. */
extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
__attribute__ ((__weak__));
-#endif
-#if HP_TIMING_AVAIL
static int
hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
{
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 5afe20feb5..cd536a0fc0 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -1,5 +1,5 @@
/* clock_gettime -- Get current time from a POSIX clockid_t. Linux version.
- Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 2003,2004,2005,2006,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
@@ -133,11 +133,19 @@ maybe_syscall_gettime_cpu (clockid_t clock_id, struct timespec *tp)
{
if (e == EINVAL)
{
+# ifdef HAVE_CLOCK_GETRES_VSYSCALL
/* Check whether the kernel supports CPU clocks at all.
If not, record it for the future. */
r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ NULL);
+# else
+ /* Check whether the kernel supports CPU clocks at all.
+ If not, record it for the future. */
+ r = INTERNAL_SYSCALL (clock_getres, err, 2,
MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
NULL);
+# endif
if (INTERNAL_SYSCALL_ERROR_P (r, err))
__libc_missing_posix_cpu_timers = 1;
}
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index 89bad440c9..86c593ee2b 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -74,6 +74,7 @@ _dl_discover_osversion (void)
#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type)
note = ((const void *) (note + 1)
+ ROUND (note->n_namesz) + ROUND (note->n_descsz));
+#undef ROUND
}
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c b/sysdeps/unix/sysv/linux/dl-vdso.c
index e1be097734..28d4bb1d42 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c
+++ b/sysdeps/unix/sysv/linux/dl-vdso.c
@@ -1,5 +1,5 @@
/* ELF symbol resolve functions for VDSO objects.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,13 +18,12 @@
02111-1307 USA. */
#include "config.h"
-#include <dl-hash.h>
#include <ldsodefs.h>
void *
internal_function
-_dl_vdso_vsym (const char *name, const char *version)
+_dl_vdso_vsym (const char *name, const struct r_found_version *vers)
{
struct link_map *map = GLRO (dl_sysinfo_map);
void *value = NULL;
@@ -37,19 +36,11 @@ _dl_vdso_vsym (const char *name, const char *version)
memset (&wsym, 0, sizeof (ElfW (Sym)));
wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
- /* Compute hash value to the version string. */
- struct r_found_version vers;
- vers.name = version;
- vers.hidden = 1;
- vers.hash = _dl_elf_hash (version);
- /* We don't have a specific file where the symbol can be found. */
- vers.filename = NULL;
-
/* Search the scope of the vdso map. */
const ElfW (Sym) *ref = &wsym;
lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
map->l_local_scope,
- &vers, 0, 0, NULL);
+ vers, 0, 0, NULL);
if (ref != NULL)
value = DL_SYMBOL_ADDRESS (result, ref);
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
new file mode 100644
index 0000000000..7e433e03ab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -0,0 +1,49 @@
+/* ELF symbol resolve functions for VDSO objects.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_VDSO_H
+#define _DL_VDSO_H 1
+
+#include <assert.h>
+#include <ldsodefs.h>
+
+#ifdef NDEBUG
+# define CHECK_HASH(var) do {} while (0)
+#else
+# include <dl-hash.h>
+# define CHECK_HASH(var) assert (var.hash == _dl_elf_hash (var.name))
+#endif
+
+/* Create version number record for lookup. */
+#define PREPARE_VERSION(var, vname, vhash) \
+ struct r_found_version var; \
+ var.name = vname; \
+ var.hidden = 1; \
+ var.hash = vhash; \
+ CHECK_HASH (var); \
+ /* We don't have a specific file where the symbol can be found. */ \
+ var.filename = NULL
+
+
+/* Functions for resolving symbols in the VDSO link map. */
+extern void *_dl_vdso_vsym (const char *name,
+ const struct r_found_version *version)
+ internal_function attribute_hidden;
+
+#endif /* dl-vdso.h */
diff --git a/sysdeps/unix/sysv/linux/fstatfs64.c b/sysdeps/unix/sysv/linux/fstatfs64.c
index 48afd1f4d1..79c9adcdc3 100644
--- a/sysdeps/unix/sysv/linux/fstatfs64.c
+++ b/sysdeps/unix/sysv/linux/fstatfs64.c
@@ -1,5 +1,6 @@
/* Return information about the filesystem on which FD resides.
- Copyright (C) 1996,1997,1998,1999,2000,2003 Free Software Foundation, Inc.
+ Copyright (C) 1996,1997,1998,1999,2000,2003,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
@@ -22,6 +23,7 @@
#include <sys/statfs.h>
#include <stddef.h>
#include <sysdep.h>
+#include <kernel-features.h>
/* Defined in statfs64.c. */
extern int __no_statfs64 attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c
index c1c416abd7..1b9add40d7 100644
--- a/sysdeps/unix/sysv/linux/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/fxstatat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 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
@@ -30,6 +30,7 @@
#include <sysdep.h>
#include <sys/syscall.h>
#include <bp-checks.h>
+#include <kernel-features.h>
#include <xstatconv.h>
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
index 72c60ec240..34bc3c26ab 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004
+/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jes Sorensen <jes@linuxcare.com>, July 2000
@@ -25,6 +25,8 @@
#ifndef _BITS_SIGCONTEXT_H
#define _BITS_SIGCONTEXT_H 1
+#define __need_size_t
+#include <stddef.h>
#include <bits/sigstack.h>
struct ia64_fpreg
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index 66f0ac1317..6bd6bda3b0 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
+/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -28,6 +28,7 @@
#include <sys/ioctl.h>
#include <bits/libc-lock.h>
#include <not-cancel.h>
+#include <kernel-features.h>
#include "netlinkaccess.h"
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 02e6935538..9aa9abac3b 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -33,6 +33,7 @@
#include <sysdep.h>
#include <time.h>
#include <unistd.h>
+#include <kernel-features.h>
#include "netlinkaccess.h"
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index f8116d8885..aab3df348e 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -428,29 +428,37 @@
# define __ASSUME_TMPFS_NAME 1
#endif
-/* pselect was introduced just after 2.6.16-rc1. Due to the way the
- kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
+/* pselect/ppoll were introduced just after 2.6.16-rc1. Due to the way
+ the kernel versions are advertised we can only rely on 2.6.17 to have
+ the code. On x86_64 and SH this appeared first in 2.6.19-rc1,
+ on ia64 in 2.6.22-rc1 and on alpha just after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __x86_64__ && !defined __sh__ && !defined __ia64__ \
+ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 \
+ && (defined __x86_64__ || defined __sh__)) \
+ || (__LINUX_KERNEL_VERSION >= 0x020616 && defined __ia64__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_PSELECT 1
-#endif
-
-/* ppoll was introduced just after 2.6.16-rc1. Due to the way the
- kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
-# define __ASSUME_PPOLL 1
+# define __ASSUME_PPOLL 1
#endif
/* The *at syscalls were introduced just after 2.6.16-rc1. Due to the way the
kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611
+ the code. On PPC they were introduced in 2.6.17-rc1, on SH in 2.6.19-rc1
+ and on Alpha just after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_ATFCTS 1
#endif
/* Support for inter-process robust mutexes was added in 2.6.17. */
-#if __LINUX_KERNEL_VERSION >= 0x020611
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_SET_ROBUST_LIST 1
#endif
@@ -459,8 +467,11 @@
# define __ASSUME_FUTEX_LOCK_PI 1
#endif
-/* Support for utimensat syscall was added in 2.6.22. */
-#if __LINUX_KERNEL_VERSION >= 0x020616
+/* Support for utimensat syscall was added in 2.6.22, on alpha and s390
+ only after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020616 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || __LINUX_KERNEL_VERSION >= 0x020617)
# define __ASSUME_UTIMENSAT 1
#endif
@@ -469,7 +480,10 @@
# define __ASSUME_PRIVATE_FUTEX 1
#endif
-/* Support for fallocate was added in 2.6.23. */
-#if __LINUX_KERNEL_VERSION >= 0x020617
+/* Support for fallocate was added in 2.6.23, on s390
+ only after 2.6.23-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020617 \
+ && ((!defined __s390__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020618 && defined __s390__))
# define __ASSUME_FALLOCATE 1
#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index ecd8057951..d1281cf469 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -8,5 +8,5 @@ gen-as-const-headers += ucontext_i.sym
endif
ifeq ($(subdir),elf)
-routines += dl-vdso
+sysdep_routines += dl-vdso
endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
index f20a5a175c..746d9ced4a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -23,7 +23,7 @@
#ifdef SHARED
-extern void *__vdso_gettimeofday;
+extern void *__vdso_gettimeofday attribute_hidden;
extern void *__vdso_clock_gettime;
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index a71cfa5b06..d1f321c44d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -24,23 +24,6 @@
#include <bp-start.h>
#include <bp-sym.h>
-int __cache_line_size attribute_hidden;
-/* The main work is done in the generic function. */
-#define LIBC_START_MAIN generic_start_main
-#define LIBC_START_DISABLE_INLINE
-#define LIBC_START_MAIN_AUXVEC_ARG
-#define MAIN_AUXVEC_ARG
-#define INIT_MAIN_ARGS
-#include <csu/libc-start.c>
-
-struct startup_info
- {
- void *__unbounded sda_base;
- int (*main) (int, char **, char **, void *);
- int (*init) (int, char **, char **, void *);
- void (*fini) (void);
- };
-
#ifdef SHARED
# include <sys/time.h>
@@ -50,27 +33,46 @@ struct startup_info
# undef __clock_getres
# include <bits/libc-vdso.h>
-void *__vdso_gettimeofday;
+void *__vdso_gettimeofday attribute_hidden;
void *__vdso_clock_gettime;
void *__vdso_clock_getres;
void *__vdso_get_tbfreq;
-static inline void _libc_vdso_platform_setup (void)
- {
- __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday",
- "LINUX_2.6.15");
+static inline void
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
+ __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
- __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime",
- "LINUX_2.6.15");
+ __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
- __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres",
- "LINUX_2.6.15");
+ __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
+
+ __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615);
+}
- __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq",
- "LINUX_2.6.15");
- }
+# define VDSO_SETUP _libc_vdso_platform_setup
#endif
+
+int __cache_line_size attribute_hidden;
+/* The main work is done in the generic function. */
+#define LIBC_START_MAIN generic_start_main
+#define LIBC_START_DISABLE_INLINE
+#define LIBC_START_MAIN_AUXVEC_ARG
+#define MAIN_AUXVEC_ARG
+#define INIT_MAIN_ARGS
+#include <csu/libc-start.c>
+
+struct startup_info
+ {
+ void *__unbounded sda_base;
+ int (*main) (int, char **, char **, void *);
+ int (*init) (int, char **, char **, void *);
+ void (*fini) (void);
+ };
+
int
/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
BPs in the arglist of startup_info.main and startup_info.init. */
@@ -117,10 +119,7 @@ int
__cache_line_size = av->a_un.a_val;
break;
}
-#ifdef SHARED
- /* Resolve and initialize function pointers for VDSO functions. */
- _libc_vdso_platform_setup ();
-#endif
+
return generic_start_main (stinfo->main, argc, ubp_av, auxvec,
stinfo->init, stinfo->fini, rtld_fini,
stack_on_entry);
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index cfc86ba806..14eb3111b9 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@@ -26,9 +26,11 @@
#ifdef __NR_ppoll
+# ifndef __ASSUME_PPOLL
static int __generic_ppoll (struct pollfd *fds, nfds_t nfds,
const struct timespec *timeout,
const sigset_t *sigmask);
+# endif
int
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 0dd744f527..f39ee920cd 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@@ -26,10 +26,12 @@
#ifdef __NR_pselect6
+# ifndef __ASSUME_PSELECT
static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout,
const sigset_t *sigmask);
+# endif
int
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S b/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
index c0d7cd4590..b2db5423c3 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <kernel-features.h>
#define EINVAL 22
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S b/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
index aba4ac34e3..4c3667aaa5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <kernel-features.h>
#define EINVAL 22
#define ENOSYS 38
diff --git a/sysdeps/unix/sysv/linux/shm_open.c b/sysdeps/unix/sysv/linux/shm_open.c
index 0628427680..92d22cfa76 100644
--- a/sysdeps/unix/sysv/linux/shm_open.c
+++ b/sysdeps/unix/sysv/linux/shm_open.c
@@ -187,7 +187,7 @@ shm_open (const char *name, int oflag, mode_t mode)
if (__builtin_expect (flags, 0) >= 0)
{
-# ifndef O_CLOEXEC
+# ifdef O_CLOEXEC
if (have_o_cloexec == 0)
have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
if (have_o_cloexec < 0)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
index 9f4c02c78b..71a51ccd8a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
@@ -1,3 +1,5 @@
+#include <kernel-features.h>
+
#include "../../i386/xstat.c"
#ifdef __NR_stat64
diff --git a/sysdeps/unix/sysv/linux/statfs64.c b/sysdeps/unix/sysv/linux/statfs64.c
index 9ccc7a7d69..c3d17b5edd 100644
--- a/sysdeps/unix/sysv/linux/statfs64.c
+++ b/sysdeps/unix/sysv/linux/statfs64.c
@@ -1,5 +1,5 @@
/* Return information about the filesystem on which FILE resides.
- Copyright (C) 1996-2000,2003,2004 Free Software Foundation, Inc.
+ Copyright (C) 1996-2000,2003,2004,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
@@ -22,6 +22,7 @@
#include <sys/statfs.h>
#include <stddef.h>
#include <sysdep.h>
+#include <kernel-features.h>
# if __ASSUME_STATFS64 == 0
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index bdad5063df..6e2741a967 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,3 +13,7 @@ endif
ifeq ($(subdir),csu)
gen-as-const-headers += ucontext_i.sym
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/Versions b/sysdeps/unix/sysv/linux/x86_64/Versions
index fd1b3cc296..34c100bfd2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Versions
+++ b/sysdeps/unix/sysv/linux/x86_64/Versions
@@ -6,4 +6,7 @@ libc {
modify_ldt;
}
+ GLIBC_PRIVATE {
+ __vdso_clock_gettime;
+ }
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
index a7dcb2e5ff..6e08d3b203 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
@@ -1,5 +1,5 @@
-/* ELF symbol resolve functions for VDSO objects.
- Copyright (C) 2005 Free Software Foundation, Inc.
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,11 +17,19 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#ifndef _DL_VDSO_H
-#define _DL_VDSO_H 1
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
-/* Functions for resolving symbols in the VDSO link map. */
-extern void *_dl_vdso_vsym (const char *name, const char *version)
- internal_function attribute_hidden;
+#include <time.h>
+#include <sys/time.h>
-#endif /* dl-vdso.h */
+#ifdef SHARED
+
+extern int (*__vdso_gettimeofday) (struct timeval *, void *)
+ attribute_hidden;
+
+extern int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
index 84a99b0406..f618e738b1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 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
@@ -28,7 +28,12 @@ ENTRY (__gettimeofday)
/* Align stack. */
sub $0x8, %rsp
cfi_adjust_cfa_offset(8)
+#ifdef SHARED
+ movq __vdso_gettimeofday(%rip), %rax
+ PTR_DEMANGLE (%rax)
+#else
movq $VSYSCALL_ADDR_vgettimeofday, %rax
+#endif
callq *%rax
/* Check error return. */
cmpl $-4095, %eax
diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-start.c b/sysdeps/unix/sysv/linux/x86_64/libc-start.c
new file mode 100644
index 0000000000..dea2e8afe4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/libc-start.c
@@ -0,0 +1,49 @@
+/* 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. */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
+
+int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("gettimeofday", &linux26);
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
+ if (p == NULL)
+ p = (void *) VSYSCALL_ADDR_vgettimeofday;
+ PTR_MANGLE (p);
+ __vdso_gettimeofday = p;
+
+ p = _dl_vdso_vsym ("clock_gettime", &linux26);
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/libc-start.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 1d9a68a046..44d5650549 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -68,14 +68,14 @@
/* 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
+# ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+# else
+# define SYSCALL_ERROR_LABEL syscall_error
+# endif
-#undef PSEUDO
-#define PSEUDO(name, syscall_name, args) \
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
@@ -83,40 +83,40 @@
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
-#undef PSEUDO_END
-#define PSEUDO_END(name) \
+# undef PSEUDO_END
+# define PSEUDO_END(name) \
SYSCALL_ERROR_HANDLER \
END (name)
-#undef PSEUDO_NOERRNO
-#define PSEUDO_NOERRNO(name, syscall_name, args) \
+# 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) \
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
END (name)
-#define ret_NOERRNO ret
+# define ret_NOERRNO ret
-#undef PSEUDO_ERRVAL
-#define PSEUDO_ERRVAL(name, syscall_name, args) \
+# 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) \
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
END (name)
-#define ret_ERRVAL ret
+# 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 \
+# 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; \
@@ -124,13 +124,13 @@
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 \
+# 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; \
@@ -138,10 +138,10 @@
movl %edx, %fs:(%rcx); \
orq $-1, %rax; \
jmp L(pseudo_end);
-#elif defined _LIBC_REENTRANT
+# elif defined _LIBC_REENTRANT
/* Store (- %rax) into errno through the GOT.
Note that errno occupies only 4 bytes. */
-# define SYSCALL_ERROR_HANDLER \
+# define SYSCALL_ERROR_HANDLER \
0: \
xorl %edx, %edx; \
subq %rax, %rdx; \
@@ -158,15 +158,15 @@
/* 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 \
+# 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 */
+# endif /* PIC */
/* The Linux/x86-64 kernel expects the system call parameters in
registers according to the following table:
@@ -204,25 +204,25 @@
Syscalls of more than 6 arguments are not supported. */
-#undef DO_CALL
-#define DO_CALL(syscall_name, args) \
+# 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
+# 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...) \
+# 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)) \
@@ -232,10 +232,10 @@
} \
(long) resultvar; })
-#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
unsigned long resultvar; \
LOAD_ARGS_##nr (args) \
@@ -245,68 +245,126 @@
: "=a" (resultvar) \
: "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
(long) resultvar; })
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+# 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) \
+# 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))
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+# ifdef SHARED
+# define INLINE_VSYSCALL(name, nr, args...) \
+ ({ \
+ __label__ out; \
+ __label__ iserr; \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret; \
+ \
+ __typeof (__vdso_##name) vdsop = __vdso_##name; \
+ PTR_DEMANGLE (vdsop); \
+ if (vdsop != NULL) \
+ { \
+ sc_ret = vdsop (args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ goto out; \
+ if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
+ goto iserr; \
+ } \
+ \
+ sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ iserr: \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ out: \
+ sc_ret; \
+ })
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ ({ \
+ __label__ out; \
+ long int v_ret; \
+ \
+ __typeof (__vdso_##name) vdsop = __vdso_##name; \
+ PTR_DEMANGLE (vdsop); \
+ if (vdsop != NULL) \
+ { \
+ v_ret = vdsop (args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
+ || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
+ goto out; \
+ } \
+ v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \
+ out: \
+ v_ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+# define HAVE_CLOCK_GETTIME_VSYSCALL 1
+
+# else
+# define INLINE_VSYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, ##args)
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL (name, err, nr, ##args)
+# endif
-#define LOAD_ARGS_0()
-#define LOAD_REGS_0
-#define ASM_ARGS_0
+# define LOAD_ARGS_0()
+# define LOAD_REGS_0
+# define ASM_ARGS_0
-#define LOAD_ARGS_1(a1) \
+# define LOAD_ARGS_1(a1) \
long int __arg1 = (long) (a1); \
LOAD_ARGS_0 ()
-#define LOAD_REGS_1 \
+# define LOAD_REGS_1 \
register long int _a1 asm ("rdi") = __arg1; \
LOAD_REGS_0
-#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
+# define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
-#define LOAD_ARGS_2(a1, a2) \
+# define LOAD_ARGS_2(a1, a2) \
long int __arg2 = (long) (a2); \
LOAD_ARGS_1 (a1)
-#define LOAD_REGS_2 \
+# define LOAD_REGS_2 \
register long int _a2 asm ("rsi") = __arg2; \
LOAD_REGS_1
-#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
+# define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
-#define LOAD_ARGS_3(a1, a2, a3) \
+# define LOAD_ARGS_3(a1, a2, a3) \
long int __arg3 = (long) (a3); \
LOAD_ARGS_2 (a1, a2)
-#define LOAD_REGS_3 \
+# define LOAD_REGS_3 \
register long int _a3 asm ("rdx") = __arg3; \
LOAD_REGS_2
-#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
+# define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
-#define LOAD_ARGS_4(a1, a2, a3, a4) \
+# define LOAD_ARGS_4(a1, a2, a3, a4) \
long int __arg4 = (long) (a4); \
LOAD_ARGS_3 (a1, a2, a3)
-#define LOAD_REGS_4 \
+# define LOAD_REGS_4 \
register long int _a4 asm ("r10") = __arg4; \
LOAD_REGS_3
-#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
+# define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
-#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+# 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 \
+# define LOAD_REGS_5 \
register long int _a5 asm ("r8") = __arg5; \
LOAD_REGS_4
-#define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
+# define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
-#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+# 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 \
+# define LOAD_REGS_6 \
register long int _a6 asm ("r9") = __arg6; \
LOAD_REGS_5
-#define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
+# define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c
index 805e339782..8210798a69 100644
--- a/sysdeps/unix/sysv/linux/xstatconv.c
+++ b/sysdeps/unix/sysv/linux/xstatconv.c
@@ -1,5 +1,6 @@
/* Convert between the kernel's `struct stat' format, and libc's.
- Copyright (C) 1991,1995-1997,2000,2002,2003 Free Software Foundation, Inc.
+ Copyright (C) 1991,1995-1997,2000,2002,2003,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
@@ -20,6 +21,7 @@
#include <errno.h>
#include <sys/stat.h>
#include <kernel_stat.h>
+#include <kernel-features.h>
#ifdef STAT_IS_KERNEL_STAT