From beca0eff14bb09906a1ab1096c81330b945098b5 Mon Sep 17 00:00:00 2001 From: manu Date: Sun, 20 Apr 2003 00:09:41 +0000 Subject: [PATCH] Fixed an ABI bug in lseek: NetBSD pads the syscallarg structure because of the off_t argument, Darwin does not. In order to get the off_t argument going through our syscall machinery, we declare it as two long arguments, and we reassemble it in darwin_sys_lseek. --- sys/compat/darwin/darwin_syscall.h | 4 +- sys/compat/darwin/darwin_syscallargs.h | 13 ++++- sys/compat/darwin/darwin_syscalls.c | 4 +- sys/compat/darwin/darwin_sysent.c | 12 ++-- sys/compat/darwin/darwin_unistd.c | 78 ++++++++++++++++++++++++++ sys/compat/darwin/files.darwin | 3 +- sys/compat/darwin/syscalls.master | 11 ++-- 7 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 sys/compat/darwin/darwin_unistd.c diff --git a/sys/compat/darwin/darwin_syscall.h b/sys/compat/darwin/darwin_syscall.h index 03ef99594b22..997898bb1c6c 100644 --- a/sys/compat/darwin/darwin_syscall.h +++ b/sys/compat/darwin/darwin_syscall.h @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_syscall.h,v 1.21 2003/01/24 21:37:02 manu Exp $ */ +/* $NetBSD: darwin_syscall.h,v 1.22 2003/04/20 00:09:41 manu Exp $ */ /* * System call numbers. @@ -381,7 +381,7 @@ /* syscall: "mmap" ret: "void *" args: "void *" "size_t" "int" "int" "int" "long" "off_t" */ #define DARWIN_SYS_mmap 197 -/* syscall: "lseek" ret: "off_t" args: "int" "int" "off_t" "int" */ +/* syscall: "lseek" ret: "off_t" args: "int" "long" "long" "int" */ #define DARWIN_SYS_lseek 199 /* syscall: "ftruncate" ret: "int" args: "int" "int" "off_t" */ diff --git a/sys/compat/darwin/darwin_syscallargs.h b/sys/compat/darwin/darwin_syscallargs.h index 118b613a430c..4c3e0e44aa0f 100644 --- a/sys/compat/darwin/darwin_syscallargs.h +++ b/sys/compat/darwin/darwin_syscallargs.h @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_syscallargs.h,v 1.21 2003/01/24 21:37:02 manu Exp $ */ +/* $NetBSD: darwin_syscallargs.h,v 1.22 2003/04/20 00:09:41 manu Exp $ */ /* * System call argument lists. @@ -197,6 +197,13 @@ struct bsd_sys_pathconf_args { syscallarg(int) name; }; +struct darwin_sys_lseek_args { + syscallarg(int) fd; + syscallarg(long) off1; + syscallarg(long) off2; + syscallarg(int) whence; +}; + struct bsd_sys_truncate_args { syscallarg(const char *) path; syscallarg(int) pad; @@ -251,7 +258,7 @@ int bsd_sys_chmod(struct lwp *, void *, register_t *); int bsd_sys_chown(struct lwp *, void *, register_t *); int sys_obreak(struct lwp *, void *, register_t *); int sys_getfsstat(struct lwp *, void *, register_t *); -int sys_lseek(struct lwp *, void *, register_t *); +int compat_43_sys_lseek(struct lwp *, void *, register_t *); int darwin_sys_getpid(struct lwp *, void *, register_t *); int bsd_sys_mount(struct lwp *, void *, register_t *); int bsd_sys_unmount(struct lwp *, void *, register_t *); @@ -405,7 +412,7 @@ int sys_getrlimit(struct lwp *, void *, register_t *); int sys_setrlimit(struct lwp *, void *, register_t *); int compat_12_sys_getdirentries(struct lwp *, void *, register_t *); int sys_mmap(struct lwp *, void *, register_t *); -int compat_43_sys_lseek(struct lwp *, void *, register_t *); +int darwin_sys_lseek(struct lwp *, void *, register_t *); int bsd_sys_truncate(struct lwp *, void *, register_t *); int sys_ftruncate(struct lwp *, void *, register_t *); int darwin_sys___sysctl(struct lwp *, void *, register_t *); diff --git a/sys/compat/darwin/darwin_syscalls.c b/sys/compat/darwin/darwin_syscalls.c index 8aaf24487926..db1a8f044f9b 100644 --- a/sys/compat/darwin/darwin_syscalls.c +++ b/sys/compat/darwin/darwin_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_syscalls.c,v 1.21 2003/01/24 21:37:02 manu Exp $ */ +/* $NetBSD: darwin_syscalls.c,v 1.22 2003/04/20 00:09:41 manu Exp $ */ /* * System call names. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: darwin_syscalls.c,v 1.21 2003/01/24 21:37:02 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: darwin_syscalls.c,v 1.22 2003/04/20 00:09:41 manu Exp $"); #if defined(_KERNEL_OPT) #include "opt_ktrace.h" diff --git a/sys/compat/darwin/darwin_sysent.c b/sys/compat/darwin/darwin_sysent.c index e120f3fb183a..e7161bc2d0ff 100644 --- a/sys/compat/darwin/darwin_sysent.c +++ b/sys/compat/darwin/darwin_sysent.c @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_sysent.c,v 1.22 2003/01/24 21:37:02 manu Exp $ */ +/* $NetBSD: darwin_sysent.c,v 1.23 2003/04/20 00:09:41 manu Exp $ */ /* * System call switch table. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: darwin_sysent.c,v 1.22 2003/01/24 21:37:02 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: darwin_sysent.c,v 1.23 2003/04/20 00:09:41 manu Exp $"); #include "opt_ktrace.h" #include "opt_nfsserver.h" @@ -71,8 +71,8 @@ struct sysent darwin_sysent[] = { sys_obreak }, /* 17 = break */ { 3, s(struct sys_getfsstat_args), 0, sys_getfsstat }, /* 18 = getfsstat */ - { 3, s(struct sys_lseek_args), 0, - sys_lseek }, /* 19 = olseek */ + { 3, s(struct compat_43_sys_lseek_args), 0, + compat_43_sys_lseek }, /* 19 = olseek */ { 0, 0, 0, darwin_sys_getpid }, /* 20 = getpid */ { 4, s(struct bsd_sys_mount_args), 0, @@ -456,8 +456,8 @@ struct sysent darwin_sysent[] = { sys_mmap }, /* 197 = mmap */ { 0, 0, 0, sys_nosys }, /* 198 = unimplemented */ - { 4, s(struct compat_43_sys_lseek_args), 0, - compat_43_sys_lseek }, /* 199 = lseek */ + { 4, s(struct darwin_sys_lseek_args), 0, + darwin_sys_lseek }, /* 199 = lseek */ { 3, s(struct bsd_sys_truncate_args), 0, bsd_sys_truncate }, /* 200 = truncate */ { 3, s(struct sys_ftruncate_args), 0, diff --git a/sys/compat/darwin/darwin_unistd.c b/sys/compat/darwin/darwin_unistd.c new file mode 100644 index 000000000000..673385e4c375 --- /dev/null +++ b/sys/compat/darwin/darwin_unistd.c @@ -0,0 +1,78 @@ +/* $NetBSD: darwin_unistd.c,v 1.1 2003/04/20 00:09:42 manu Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_compat_darwin.h" /* For COMPAT_DARWIN in mach_port.h */ +#include +__KERNEL_RCSID(0, "$NetBSD: darwin_unistd.c,v 1.1 2003/04/20 00:09:42 manu Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +int +darwin_sys_lseek(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + struct darwin_sys_lseek_args *uap = v; + struct sys_lseek_args cup; + + SCARG(&cup, fd) = SCARG(uap, fd); + SCARG(&cup, whence) = SCARG(uap, whence); + + /* + * NetBSD pads the syscallarg structure because of the + * off_t argument, Darwin does not. In order to get the off_t + * argument going through our syscall machinery, we declare + * it as two long arguments, and we reassemble them here. + */ + SCARG(&cup, offset) = (off_t)(u_long)SCARG(uap, off1); + SCARG(&cup, offset) <<= 32; + SCARG(&cup, offset) += (off_t)(u_long)SCARG(uap, off2); + + return sys_lseek(l, &cup, retval); +} diff --git a/sys/compat/darwin/files.darwin b/sys/compat/darwin/files.darwin index 47d7799184ed..466bb675a364 100644 --- a/sys/compat/darwin/files.darwin +++ b/sys/compat/darwin/files.darwin @@ -1,4 +1,4 @@ -# $NetBSD: files.darwin,v 1.9 2003/02/16 15:02:06 manu Exp $ +# $NetBSD: files.darwin,v 1.10 2003/04/20 00:09:42 manu Exp $ # # Config file description for machine-independent Darwin compat code. # Included by ports that need it. @@ -15,3 +15,4 @@ file compat/darwin/darwin_signal.c compat_darwin file compat/darwin/darwin_sysent.c compat_darwin file compat/darwin/darwin_sysctl.c compat_darwin file compat/darwin/darwin_thread.c compat_darwin +file compat/darwin/darwin_unistd.c compat_darwin diff --git a/sys/compat/darwin/syscalls.master b/sys/compat/darwin/syscalls.master index bce99173be27..a83216cd4e06 100644 --- a/sys/compat/darwin/syscalls.master +++ b/sys/compat/darwin/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.11 2003/01/22 17:47:36 christos Exp $ + $NetBSD: syscalls.master,v 1.12 2003/04/20 00:09:42 manu Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -90,8 +91,8 @@ 17 NOARGS { int sys_obreak(char *nsize); } break 18 NOARGS { int sys_getfsstat(struct statfs *buf, long bufsize, \ int flags); } -19 NOARGS { long sys_lseek(int fd, long offset, int whence); } \ - olseek +19 NOARGS { long compat_43_sys_lseek(int fd, long offset, \ + int whence); } olseek 20 STD { pid_t darwin_sys_getpid(void); } 21 NODEF { int bsd_sys_mount(const char *type, \ const char *path, int flags, void *data); } @@ -376,8 +377,8 @@ 197 NOARGS { void *sys_mmap(void *addr, size_t len, int prot, \ int flags, int fd, long pad, off_t pos); } 198 UNIMPL -199 NOARGS { off_t compat_43_sys_lseek(int fd, int pad, \ - off_t offset, int whence); } +199 STD { off_t darwin_sys_lseek(int fd, long off1, \ + long off2, int whence); } 200 NODEF { int bsd_sys_truncate(const char *path, \ int pad, off_t length); } 201 NOARGS { int sys_ftruncate(int fd, int pad, off_t length); }