aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/mips/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/mips/Versions4
-rw-r--r--sysdeps/unix/sysv/linux/mips/init-first.c44
-rw-r--r--sysdeps/unix/sysv/linux/mips/libc-vdso.h33
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/sysdep.h16
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h17
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h17
7 files changed, 133 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile
index 8127025503..c6729c15f9 100644
--- a/sysdeps/unix/sysv/linux/mips/Makefile
+++ b/sysdeps/unix/sysv/linux/mips/Makefile
@@ -96,6 +96,8 @@ ifeq ($(subdir),elf)
ifeq ($(build-shared),yes)
# This is needed for DSO loading from static binaries.
sysdep-dl-routines += dl-static
+
+sysdep_routines += dl-vdso
endif
endif
diff --git a/sysdeps/unix/sysv/linux/mips/Versions b/sysdeps/unix/sysv/linux/mips/Versions
index a56322a8eb..453f276aad 100644
--- a/sysdeps/unix/sysv/linux/mips/Versions
+++ b/sysdeps/unix/sysv/linux/mips/Versions
@@ -37,4 +37,8 @@ libc {
GLIBC_2.11 {
fallocate64;
}
+ GLIBC_PRIVATE {
+ # nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime).
+ __vdso_clock_gettime;
+ }
}
diff --git a/sysdeps/unix/sysv/linux/mips/init-first.c b/sysdeps/unix/sysv/linux/mips/init-first.c
new file mode 100644
index 0000000000..1b50f1697e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/init-first.c
@@ -0,0 +1,44 @@
+/* Initialization code run first thing by the ELF startup code.
+ Copyright (C) 2016 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
+int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+ void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
+ PTR_MANGLE (p);
+ VDSO_SYMBOL (gettimeofday) = p;
+
+ p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+ PTR_MANGLE (p);
+ VDSO_SYMBOL (clock_gettime) = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/mips/libc-vdso.h b/sysdeps/unix/sysv/linux/mips/libc-vdso.h
new file mode 100644
index 0000000000..66e5da6605
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/libc-vdso.h
@@ -0,0 +1,33 @@
+/* VDSO function pointer declarations.
+ Copyright (C) 2016 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#ifdef SHARED
+
+# include <sysdep-vdso.h>
+
+extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
+ attribute_hidden;
+extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
index 2160df7d59..2335409628 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
@@ -371,6 +371,22 @@
#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
+/* Standard MIPS syscalls have an error flag, and return a positive errno
+ when the error flag is set. Emulate this behaviour for vsyscalls so that
+ the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
+#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
+ ({ \
+ long _ret = funcptr (args); \
+ err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
+ if (err) \
+ _ret = -_ret; \
+ _ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+#define HAVE_CLOCK_GETTIME_VSYSCALL 1
+#define HAVE_GETTIMEOFDAY_VSYSCALL 1
+
#endif /* __ASSEMBLER__ */
/* Pointer mangling is not yet supported for MIPS. */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
index 466dcdef80..661b3dc6f4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
@@ -295,6 +295,23 @@
#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
+
+/* Standard MIPS syscalls have an error flag, and return a positive errno
+ when the error flag is set. Emulate this behaviour for vsyscalls so that
+ the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
+#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
+ ({ \
+ long _ret = funcptr (args); \
+ err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
+ if (err) \
+ _ret = -_ret; \
+ _ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+#define HAVE_CLOCK_GETTIME_VSYSCALL 1
+#define HAVE_GETTIMEOFDAY_VSYSCALL 1
+
#endif /* __ASSEMBLER__ */
/* Pointer mangling is not yet supported for MIPS. */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
index db8b237eb7..476eca341f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
@@ -291,6 +291,23 @@
#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
+
+/* Standard MIPS syscalls have an error flag, and return a positive errno
+ when the error flag is set. Emulate this behaviour for vsyscalls so that
+ the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
+#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
+ ({ \
+ long _ret = funcptr (args); \
+ err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
+ if (err) \
+ _ret = -_ret; \
+ _ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+#define HAVE_CLOCK_GETTIME_VSYSCALL 1
+#define HAVE_GETTIMEOFDAY_VSYSCALL 1
+
#endif /* __ASSEMBLER__ */
/* Pointer mangling is not yet supported for MIPS. */