Module Name: src
Committed By: chs
Date: Tue Nov 2 18:14:06 UTC 2010
Modified Files:
src/sys/compat/linux/common: linux_misc_notalpha.c linux_statfs.h
src/sys/compat/linux32/arch/amd64: linux32_machdep.c syscalls.master
src/sys/compat/linux32/common: linux32_misc.c linux32_types.h
Log Message:
implement the following syscalls for linux32:
truncate64
ftruncate64
profil
ioperm
iopl
setdomainname
modify_ldt
statfs64
fstatfs64
note that iopl(), ioperm() and modify_ldt() just call
the respective 64-bit handlers, which don't do anything yet.
To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.108 \
src/sys/compat/linux/common/linux_misc_notalpha.c
cvs rdiff -u -r1.4 -r1.5 src/sys/compat/linux/common/linux_statfs.h
cvs rdiff -u -r1.26 -r1.27 \
src/sys/compat/linux32/arch/amd64/linux32_machdep.c
cvs rdiff -u -r1.56 -r1.57 src/sys/compat/linux32/arch/amd64/syscalls.master
cvs rdiff -u -r1.19 -r1.20 src/sys/compat/linux32/common/linux32_misc.c
cvs rdiff -u -r1.13 -r1.14 src/sys/compat/linux32/common/linux32_types.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/compat/linux/common/linux_misc_notalpha.c
diff -u src/sys/compat/linux/common/linux_misc_notalpha.c:1.107 src/sys/compat/linux/common/linux_misc_notalpha.c:1.108
--- src/sys/compat/linux/common/linux_misc_notalpha.c:1.107 Wed Jul 7 01:30:35 2010
+++ src/sys/compat/linux/common/linux_misc_notalpha.c Tue Nov 2 18:14:05 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_misc_notalpha.c,v 1.107 2010/07/07 01:30:35 chs Exp $ */
+/* $NetBSD: linux_misc_notalpha.c,v 1.108 2010/11/02 18:14:05 chs Exp $ */
/*-
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -31,7 +31,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.107 2010/07/07 01:30:35 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.108 2010/11/02 18:14:05 chs Exp $");
+
+/*
+ * Note that we must NOT include "opt_compat_linux32.h" here,
+ * the maze of ifdefs below relies on COMPAT_LINUX32 only being
+ * defined when this file is built for linux32.
+ */
#include <sys/param.h>
#include <sys/systm.h>
@@ -61,6 +67,7 @@
#include <compat/linux/common/linux_util.h>
#include <compat/linux/common/linux_ipc.h>
#include <compat/linux/common/linux_sem.h>
+#include <compat/linux/common/linux_statfs.h>
#include <compat/linux/linux_syscallargs.h>
@@ -79,10 +86,6 @@
#endif
#ifndef COMPAT_LINUX32
-#if !defined(__amd64__)
-static void bsd_to_linux_statfs64(const struct statvfs *,
- struct linux_statfs64 *);
-#endif
/*
* Alarm. This is a libc call which uses setitimer(2) in NetBSD.
@@ -401,49 +404,6 @@
return 0;
}
-#endif /* !amd64 */
-
-#if !defined(__amd64__)
-/*
- * Convert NetBSD statvfs structure to Linux statfs64 structure.
- * See comments in bsd_to_linux_statfs() for further background.
- * We can safely pass correct bsize and frsize here, since Linux glibc
- * statvfs() doesn't use statfs64().
- */
-static void
-bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp)
-{
- int i, div;
-
- for (i = 0; i < linux_fstypes_cnt; i++) {
- if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) {
- lsp->l_ftype = linux_fstypes[i].linux;
- break;
- }
- }
-
- if (i == linux_fstypes_cnt) {
- DPRINTF(("unhandled fstype in linux emulation: %s\n",
- bsp->f_fstypename));
- lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC;
- }
-
- div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1;
- if (div == 0)
- div = 1;
- lsp->l_fbsize = bsp->f_bsize;
- lsp->l_ffrsize = bsp->f_frsize;
- lsp->l_fblocks = bsp->f_blocks / div;
- lsp->l_fbfree = bsp->f_bfree / div;
- lsp->l_fbavail = bsp->f_bavail / div;
- lsp->l_ffiles = bsp->f_files;
- lsp->l_fffree = bsp->f_ffree / div;
- /* Linux sets the fsid to 0..., we don't */
- lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0];
- lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1];
- lsp->l_fnamelen = bsp->f_namemax;
- (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare));
-}
/*
* Implement the fs stat functions. Straightforward.
@@ -497,5 +457,5 @@
STATVFSBUF_PUT(sb);
return error;
}
-#endif /* !__m68k__ && !__amd64__ */
+#endif /* !__amd64__ */
#endif /* !COMPAT_LINUX32 */
Index: src/sys/compat/linux/common/linux_statfs.h
diff -u src/sys/compat/linux/common/linux_statfs.h:1.4 src/sys/compat/linux/common/linux_statfs.h:1.5
--- src/sys/compat/linux/common/linux_statfs.h:1.4 Sun Mar 15 15:55:51 2009
+++ src/sys/compat/linux/common/linux_statfs.h Tue Nov 2 18:14:05 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_statfs.h,v 1.4 2009/03/15 15:55:51 cegger Exp $ */
+/* $NetBSD: linux_statfs.h,v 1.5 2010/11/02 18:14:05 chs Exp $ */
/*-
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@@ -33,15 +33,17 @@
#ifndef _LINUX_STATFS_H
#define _LINUX_STATFS_H
-static void bsd_to_linux_statfs(const struct statvfs *,
+static void __unused bsd_to_linux_statfs(const struct statvfs *,
struct linux_statfs *);
+static void __unused bsd_to_linux_statfs64(const struct statvfs *,
+ struct linux_statfs64 *);
/*
* Convert NetBSD statvfs structure to Linux statfs structure.
* Linux doesn't have f_flag, and we can't set f_frsize due
* to glibc statvfs() bug (see below).
*/
-static void
+static void __unused
bsd_to_linux_statfs(const struct statvfs *bsp, struct linux_statfs *lsp)
{
int i;
@@ -83,4 +85,43 @@
(void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare));
}
+/*
+ * Convert NetBSD statvfs structure to Linux statfs64 structure.
+ * See comments in bsd_to_linux_statfs() for further background.
+ * We can safely pass correct bsize and frsize here, since Linux glibc
+ * statvfs() doesn't use statfs64().
+ */
+static void __unused
+bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp)
+{
+ int i, div;
+
+ for (i = 0; i < linux_fstypes_cnt; i++) {
+ if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) {
+ lsp->l_ftype = linux_fstypes[i].linux;
+ break;
+ }
+ }
+
+ if (i == linux_fstypes_cnt) {
+ lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC;
+ }
+
+ div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1;
+ if (div == 0)
+ div = 1;
+ lsp->l_fbsize = bsp->f_bsize;
+ lsp->l_ffrsize = bsp->f_frsize;
+ lsp->l_fblocks = bsp->f_blocks / div;
+ lsp->l_fbfree = bsp->f_bfree / div;
+ lsp->l_fbavail = bsp->f_bavail / div;
+ lsp->l_ffiles = bsp->f_files;
+ lsp->l_fffree = bsp->f_ffree / div;
+ /* Linux sets the fsid to 0..., we don't */
+ lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0];
+ lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1];
+ lsp->l_fnamelen = bsp->f_namemax;
+ (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare));
+}
+
#endif /* !_LINUX_STATFS_H */
Index: src/sys/compat/linux32/arch/amd64/linux32_machdep.c
diff -u src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.26 src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.27
--- src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.26 Mon Jul 12 02:55:17 2010
+++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c Tue Nov 2 18:14:06 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: linux32_machdep.c,v 1.26 2010/07/12 02:55:17 christos Exp $ */
+/* $NetBSD: linux32_machdep.c,v 1.27 2010/11/02 18:14:06 chs Exp $ */
/*-
* Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -31,7 +31,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.26 2010/07/12 02:55:17 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.27 2010/11/02 18:14:06 chs Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -513,3 +513,19 @@
/* glibc doesn't actually call this. */
return ENOSYS;
}
+
+int
+linux32_sys_modify_ldt(struct lwp *l, const struct linux32_sys_modify_ldt_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(int) func;
+ syscallarg(netbsd32_charp) ptr;
+ syscallarg(netbsd32_size_t) bytecount;
+ } */
+ struct linux_sys_modify_ldt_args ua;
+
+ NETBSD32TO64_UAP(func);
+ NETBSD32TOP_UAP(ptr, void *);
+ NETBSD32TOX_UAP(bytecount, size_t);
+ return linux_sys_modify_ldt(l, &ua, retval);
+}
Index: src/sys/compat/linux32/arch/amd64/syscalls.master
diff -u src/sys/compat/linux32/arch/amd64/syscalls.master:1.56 src/sys/compat/linux32/arch/amd64/syscalls.master:1.57
--- src/sys/compat/linux32/arch/amd64/syscalls.master:1.56 Wed Jul 7 01:30:35 2010
+++ src/sys/compat/linux32/arch/amd64/syscalls.master Tue Nov 2 18:14:06 2010
@@ -1,4 +1,4 @@
- $NetBSD: syscalls.master,v 1.56 2010/07/07 01:30:35 chs Exp $
+ $NetBSD: syscalls.master,v 1.57 2010/11/02 18:14:06 chs Exp $
; NetBSD i386 COMPAT_LINUX32 system call name/number "master" file.
; (See syscalls.conf to see what it is processed into.)
@@ -193,11 +193,14 @@
linux32_gid16_t gid); }
96 STD { int|linux32_sys||getpriority(int which, int who); }
97 NOARGS { int|netbsd32||setpriority(int which, int who, int prio); }
-98 UNIMPL profil
+98 NOARGS { int|netbsd32||profil(netbsd32_voidp samples, \
+ netbsd32_size_t size, netbsd32_u_long offset, \
+ u_int scale); }
99 STD { int|linux32_sys||statfs(netbsd32_charp path, \
linux32_statfsp sp); }
100 STD { int|linux32_sys||fstatfs(int fd, linux32_statfsp sp); }
-101 UNIMPL ioperm
+101 NOARGS { int|linux_sys||ioperm(unsigned int lo, \
+ unsigned int hi, int val); }
102 STD { int|linux32_sys||socketcall(int what, netbsd32_voidp args); }
103 UNIMPL syslog
104 NOARGS { int|compat_50_netbsd32||setitimer(int which, \
@@ -211,7 +214,7 @@
108 STD { int|linux32_sys||fstat(int fd, \
linux32_statp sp); }
109 STD { int|linux32_sys||olduname(linux32_oldutsnamep_t up); }
-110 UNIMPL iopl
+110 NOARGS { int|linux_sys||iopl(int level); }
111 UNIMPL vhangup
112 UNIMPL idle
113 UNIMPL vm86old
@@ -226,9 +229,11 @@
120 STD { int|linux32_sys||clone(int flags, netbsd32_voidp stack, \
netbsd32_voidp parent_tidptr, netbsd32_voidp tls, \
netbsd32_voidp child_tidptr); }
-121 UNIMPL setdomainname
+121 STD { int|linux32_sys||setdomainname(netbsd32_charp domainname, \
+ int len); }
122 STD { int|linux32_sys||uname(linux32_utsnamep up); }
-123 UNIMPL modify_ldt
+123 STD { int|linux32_sys||modify_ldt(int func, netbsd32_charp ptr, \
+ netbsd32_size_t bytecount); }
124 UNIMPL adjtimex
125 STD { int|linux32_sys||mprotect(netbsd32_voidp start, \
netbsd32_size_t len, int prot); }
@@ -339,8 +344,10 @@
192 STD { linux32_off_t|linux32_sys||mmap2(netbsd32_u_long addr, \
netbsd32_size_t len, int prot, int flags, int fd, \
linux32_off_t offset); }
-193 UNIMPL truncate64
-194 UNIMPL ftruncate64
+193 STD { int|linux32_sys||truncate64(netbsd32_charp path, \
+ uint32_t lenlo, uint32_t lenhi); }
+194 STD { int|linux32_sys||ftruncate64(unsigned int fd, \
+ uint32_t lenlo, uint32_t lenhi); }
195 STD { int|linux32_sys||stat64(netbsd32_charp path, \
linux32_stat64p sp); }
196 STD { int|linux32_sys||lstat64(netbsd32_charp path, \
@@ -440,8 +447,10 @@
linux32_timespecp_t tp); }
267 STD { int|linux32_sys||clock_nanosleep(clockid_t which, int flags, \
linux32_timespecp_t rqtp, linux32_timespecp_t rmtp); }
-268 UNIMPL statfs64
-269 UNIMPL fstatfs64
+268 STD { int|linux32_sys||statfs64(netbsd32_charp path, \
+ netbsd32_size_t sz, linux32_statfs64p sp); }
+269 STD { int|linux32_sys||fstatfs64(int fd, \
+ netbsd32_size_t sz, linux32_statfs64p sp); }
270 STD { int|linux32_sys||tgkill(int tgid, int tid, int sig); }
271 UNIMPL utimes
272 UNIMPL fadvise64_64
Index: src/sys/compat/linux32/common/linux32_misc.c
diff -u src/sys/compat/linux32/common/linux32_misc.c:1.19 src/sys/compat/linux32/common/linux32_misc.c:1.20
--- src/sys/compat/linux32/common/linux32_misc.c:1.19 Wed Jul 7 01:30:35 2010
+++ src/sys/compat/linux32/common/linux32_misc.c Tue Nov 2 18:14:06 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $ */
+/* $NetBSD: linux32_misc.c,v 1.20 2010/11/02 18:14:06 chs Exp $ */
/*-
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.19 2010/07/07 01:30:35 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.20 2010/11/02 18:14:06 chs Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -114,6 +114,50 @@
return error;
}
+int
+linux32_sys_statfs64(struct lwp *l, const struct linux32_sys_statfs64_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(const netbsd32_charp char) path;
+ syscallarg(linux32_statfs64p) sp;
+ } */
+ struct statvfs *sb;
+ struct linux_statfs64 ltmp;
+ int error;
+
+ sb = STATVFSBUF_GET();
+ error = do_sys_pstatvfs(l, SCARG_P32(uap, path), ST_WAIT, sb);
+ if (error == 0) {
+ bsd_to_linux_statfs64(sb, <mp);
+ error = copyout(<mp, SCARG_P32(uap, sp), sizeof ltmp);
+ }
+
+ STATVFSBUF_PUT(sb);
+ return error;
+}
+
+int
+linux32_sys_fstatfs64(struct lwp *l, const struct linux32_sys_fstatfs64_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(int) fd;
+ syscallarg(linux32_statfs64p) sp;
+ } */
+ struct statvfs *sb;
+ struct linux_statfs64 ltmp;
+ int error;
+
+ sb = STATVFSBUF_GET();
+ error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
+ if (error == 0) {
+ bsd_to_linux_statfs64(sb, <mp);
+ error = copyout(<mp, SCARG_P32(uap, sp), sizeof ltmp);
+ }
+ STATVFSBUF_PUT(sb);
+
+ return error;
+}
+
extern const int linux_ptrace_request_map[];
int
@@ -261,6 +305,52 @@
struct linux_sys_get_robust_list_args ua;
NETBSD32TOP_UAP(head, struct robust_list_head *);
- NETBSD32TOP_UAP(head, size_t *);
+ NETBSD32TOP_UAP(len, size_t *);
return linux_sys_get_robust_list(l, &ua, retval);
}
+
+int
+linux32_sys_truncate64(struct lwp *l, const struct linux32_sys_truncate64_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(netbsd32_charp) path;
+ syscallarg(off_t) length;
+ } */
+ struct sys_truncate_args ua;
+
+ /* Linux doesn't have the 'pad' pseudo-parameter */
+ NETBSD32TOP_UAP(path, const char *);
+ SCARG(&ua, PAD) = 0;
+ SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo);
+ return sys_truncate(l, &ua, retval);
+}
+
+int
+linux32_sys_ftruncate64(struct lwp *l, const struct linux32_sys_ftruncate64_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(unsigned int) fd;
+ syscallarg(off_t) length;
+ } */
+ struct sys_ftruncate_args ua;
+
+ /* Linux doesn't have the 'pad' pseudo-parameter */
+ NETBSD32TO64_UAP(fd);
+ SCARG(&ua, PAD) = 0;
+ SCARG(&ua, length) = ((off_t)SCARG(uap, lenhi) << 32) + SCARG(uap, lenlo);
+ return sys_ftruncate(l, &ua, retval);
+}
+
+int
+linux32_sys_setdomainname(struct lwp *l, const struct linux32_sys_setdomainname_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(netbsd32_charp) domainname;
+ syscallarg(int) len;
+ } */
+ struct linux_sys_setdomainname_args ua;
+
+ NETBSD32TOP_UAP(domainname, char);
+ NETBSD32TO64_UAP(len);
+ return linux_sys_setdomainname(l, &ua, retval);
+}
Index: src/sys/compat/linux32/common/linux32_types.h
diff -u src/sys/compat/linux32/common/linux32_types.h:1.13 src/sys/compat/linux32/common/linux32_types.h:1.14
--- src/sys/compat/linux32/common/linux32_types.h:1.13 Sat Sep 11 20:53:04 2010
+++ src/sys/compat/linux32/common/linux32_types.h Tue Nov 2 18:14:06 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: linux32_types.h,v 1.13 2010/09/11 20:53:04 chs Exp $ */
+/* $NetBSD: linux32_types.h,v 1.14 2010/11/02 18:14:06 chs Exp $ */
/*-
* Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -46,6 +46,7 @@
typedef netbsd32_pointer_t linux32_stat64p;
typedef netbsd32_pointer_t linux32_statp;
typedef netbsd32_pointer_t linux32_statfsp;
+typedef netbsd32_pointer_t linux32_statfs64p;
typedef netbsd32_pointer_t linux32_sigactionp_t;
typedef netbsd32_pointer_t linux32_sigsetp_t;
typedef netbsd32_pointer_t linux32___sysctlp_t;