summaryrefslogtreecommitdiffstats
path: root/sys/amd64/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64/linux')
-rw-r--r--sys/amd64/linux/linux_proto.h2
-rw-r--r--sys/amd64/linux/linux_syscall.h2
-rw-r--r--sys/amd64/linux/linux_syscalls.c2
-rw-r--r--sys/amd64/linux/linux_sysent.c2
-rw-r--r--sys/amd64/linux/linux_systrace_args.c12
-rw-r--r--sys/amd64/linux/linux_sysvec.c51
-rw-r--r--sys/amd64/linux/syscalls.master6
7 files changed, 63 insertions, 14 deletions
diff --git a/sys/amd64/linux/linux_proto.h b/sys/amd64/linux/linux_proto.h
index eedd423..0a0cbe6 100644
--- a/sys/amd64/linux/linux_proto.h
+++ b/sys/amd64/linux/linux_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin
+ * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 294368 2016-01-20 01:09:53Z jhb
*/
#ifndef _LINUX_SYSPROTO_H_
diff --git a/sys/amd64/linux/linux_syscall.h b/sys/amd64/linux/linux_syscall.h
index c8d811a..874651c 100644
--- a/sys/amd64/linux/linux_syscall.h
+++ b/sys/amd64/linux/linux_syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin
+ * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 294368 2016-01-20 01:09:53Z jhb
*/
#define LINUX_SYS_read 0
diff --git a/sys/amd64/linux/linux_syscalls.c b/sys/amd64/linux/linux_syscalls.c
index 5c1e1a2..fcea91e 100644
--- a/sys/amd64/linux/linux_syscalls.c
+++ b/sys/amd64/linux/linux_syscalls.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin
+ * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 294368 2016-01-20 01:09:53Z jhb
*/
const char *linux_syscallnames[] = {
diff --git a/sys/amd64/linux/linux_sysent.c b/sys/amd64/linux/linux_sysent.c
index 97a15cc..14d5c87 100644
--- a/sys/amd64/linux/linux_sysent.c
+++ b/sys/amd64/linux/linux_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 293592 2016-01-09 17:54:37Z dchagin
+ * created from FreeBSD: stable/10/sys/amd64/linux/syscalls.master 294368 2016-01-20 01:09:53Z jhb
*/
#include <sys/param.h>
diff --git a/sys/amd64/linux/linux_systrace_args.c b/sys/amd64/linux/linux_systrace_args.c
index 529e768..d649eed 100644
--- a/sys/amd64/linux/linux_systrace_args.c
+++ b/sys/amd64/linux/linux_systrace_args.c
@@ -73,8 +73,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
/* poll */
case 7: {
struct poll_args *p = params;
- iarg[0] = p->*; /* struct pollfd */
- uarg[1] = p->nfds; /* unsigned int */
+ uarg[0] = (intptr_t) p->fds; /* struct pollfd * */
+ uarg[1] = p->nfds; /* u_int */
iarg[2] = p->timeout; /* int */
*n_args = 3;
break;
@@ -591,7 +591,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
iarg[0] = p->semid; /* l_int */
iarg[1] = p->semnum; /* l_int */
iarg[2] = p->cmd; /* l_int */
- uarg[3] = p->arg; /* union l_semun */
+ uarg[3] = p->arg.buf; /* union l_semun */
*n_args = 4;
break;
}
@@ -1327,7 +1327,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
/* settimeofday */
case 164: {
struct settimeofday_args *p = params;
- uarg[0] = (intptr_t) p->tp; /* struct l_timeval * */
+ uarg[0] = (intptr_t) p->tv; /* struct l_timeval * */
uarg[1] = (intptr_t) p->tzp; /* struct timezone * */
*n_args = 2;
break;
@@ -2380,10 +2380,10 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 7:
switch(ndx) {
case 0:
- p = "struct pollfd";
+ p = "struct pollfd *";
break;
case 1:
- p = "unsigned int";
+ p = "u_int";
break;
case 2:
p = "int";
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index 37c1b69..d53a266 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -129,6 +129,7 @@ static void linux_set_syscall_retval(struct thread *td, int error);
static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
static void linux_exec_setregs(struct thread *td, struct image_params *imgp,
u_long stack);
+static int linux_vsyscall(struct thread *td);
/*
* Linux syscalls return negative errno's, we do positive and map them
@@ -746,6 +747,53 @@ exec_linux_imgact_try(struct image_params *imgp)
return(error);
}
+#define LINUX_VSYSCALL_START (-10UL << 20)
+#define LINUX_VSYSCALL_SZ 1024
+
+const unsigned long linux_vsyscall_vector[] = {
+ LINUX_SYS_gettimeofday,
+ LINUX_SYS_linux_time,
+ /* getcpu not implemented */
+};
+
+static int
+linux_vsyscall(struct thread *td)
+{
+ struct trapframe *frame;
+ uint64_t retqaddr;
+ int code, traced;
+ int error;
+
+ frame = td->td_frame;
+
+ /* Check %rip for vsyscall area */
+ if (__predict_true(frame->tf_rip < LINUX_VSYSCALL_START))
+ return (EINVAL);
+ if ((frame->tf_rip & (LINUX_VSYSCALL_SZ - 1)) != 0)
+ return (EINVAL);
+ code = (frame->tf_rip - LINUX_VSYSCALL_START) / LINUX_VSYSCALL_SZ;
+ if (code >= nitems(linux_vsyscall_vector))
+ return (EINVAL);
+
+ /*
+ * vsyscall called as callq *(%rax), so we must
+ * use return address from %rsp and also fixup %rsp
+ */
+ error = copyin((void *)frame->tf_rsp, &retqaddr, sizeof(retqaddr));
+ if (error)
+ return (error);
+
+ frame->tf_rip = retqaddr;
+ frame->tf_rax = linux_vsyscall_vector[code];
+ frame->tf_rsp += 8;
+
+ traced = (frame->tf_flags & PSL_T);
+
+ amd64_syscall(td, traced);
+
+ return (0);
+}
+
struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
@@ -781,7 +829,8 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
- .sv_thread_detach = linux_thread_detach
+ .sv_thread_detach = linux_thread_detach,
+ .sv_trap = linux_vsyscall,
};
static void
diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master
index d840f88..87c8000 100644
--- a/sys/amd64/linux/syscalls.master
+++ b/sys/amd64/linux/syscalls.master
@@ -49,8 +49,8 @@
struct l_newstat *buf); }
6 AUE_LSTAT STD { int linux_newlstat(char *path, \
struct l_newstat *buf); }
-7 AUE_POLL NOPROTO { int poll(struct pollfd*, \
- unsigned int nfds, int timeout); }
+7 AUE_POLL NOPROTO { int poll(struct pollfd *fds, u_int nfds, \
+ int timeout); }
8 AUE_LSEEK STD { int linux_lseek(l_uint fdes, l_off_t off, \
l_int whence); }
9 AUE_MMAP STD { int linux_mmap2(l_ulong addr, l_ulong len, \
@@ -316,7 +316,7 @@
161 AUE_CHROOT NOPROTO { int chroot(char *path); }
162 AUE_SYNC NOPROTO { int sync(void); }
163 AUE_ACCT NOPROTO { int acct(char *path); }
-164 AUE_SETTIMEOFDAY NOPROTO { int settimeofday(struct l_timeval *tp, struct timezone *tzp); }
+164 AUE_SETTIMEOFDAY NOPROTO { int settimeofday(struct l_timeval *tv, struct timezone *tzp); }
165 AUE_MOUNT STD { int linux_mount(char *specialfile, \
char *dir, char *filesystemtype, \
l_ulong rwflag, void *data); }
OpenPOWER on IntegriCloud