Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_compat_50_sysv.c revision 1.2
      1 /*	$NetBSD: netbsd32_compat_50_sysv.c,v 1.2 2019/01/27 02:08:40 pgoyette Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Christos Zoulas.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_50_sysv.c,v 1.2 2019/01/27 02:08:40 pgoyette Exp $");
     40 
     41 #if defined(_KERNEL_OPT)
     42 #include "opt_sysv.h"
     43 #include "opt_compat_netbsd.h"
     44 #endif
     45 
     46 #include <sys/param.h>
     47 #include <sys/systm.h>
     48 #include <sys/module.h>
     49 #include <sys/msg.h>
     50 #include <sys/sem.h>
     51 #include <sys/shm.h>
     52 
     53 #include <sys/syscallvar.h>
     54 
     55 #include <compat/netbsd32/netbsd32.h>
     56 #include <compat/netbsd32/netbsd32_syscall.h>
     57 #include <compat/netbsd32/netbsd32_syscallargs.h>
     58 #include <compat/netbsd32/netbsd32_conv.h>
     59 
     60 #if defined(COMPAT_50)
     61 
     62 #if defined(SYSVSEM)
     63 
     64 int
     65 compat_50_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval)
     66 {
     67 	return do_netbsd32___semctl14(l, uap, retval, NULL);
     68 }
     69 
     70 int
     71 do_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval, void *vkarg)
     72 {
     73 	/* {
     74 		syscallarg(int) semid;
     75 		syscallarg(int) semnum;
     76 		syscallarg(int) cmd;
     77 		syscallarg(netbsd32_semun50p_t) arg;
     78 	} */
     79 	struct semid_ds sembuf;
     80 	struct netbsd32_semid_ds50 sembuf32;
     81 	int cmd, error;
     82 	void *pass_arg;
     83 	union __semun karg;
     84 	union netbsd32_semun50 karg32;
     85 
     86 	cmd = SCARG(uap, cmd);
     87 
     88 	switch (cmd) {
     89 	case IPC_SET:
     90 	case IPC_STAT:
     91 		pass_arg = &sembuf;
     92 		break;
     93 
     94 	case GETALL:
     95 	case SETVAL:
     96 	case SETALL:
     97 		pass_arg = &karg;
     98 		break;
     99 	default:
    100 		pass_arg = NULL;
    101 		break;
    102 	}
    103 
    104 	if (pass_arg) {
    105 		if (vkarg != NULL)
    106 			karg32 = *(union netbsd32_semun50 *)vkarg;
    107 		else {
    108 			error = copyin(SCARG_P32(uap, arg), &karg32,
    109 					sizeof(karg32));
    110 			if (error)
    111 				return error;
    112 		}
    113 		if (pass_arg == &karg) {
    114 			switch (cmd) {
    115 			case GETALL:
    116 			case SETALL:
    117 				karg.array = NETBSD32PTR64(karg32.array);
    118 				break;
    119 			case SETVAL:
    120 				karg.val = karg32.val;
    121 				break;
    122 			}
    123 		}
    124 		if (cmd == IPC_SET) {
    125 			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
    126 			    sizeof(sembuf32));
    127 			if (error)
    128 				return (error);
    129 			netbsd32_to_semid_ds50(&sembuf32, &sembuf);
    130 		}
    131 	}
    132 
    133 	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
    134 	    pass_arg, retval);
    135 
    136 	if (error == 0 && cmd == IPC_STAT) {
    137 		netbsd32_from_semid_ds50(&sembuf, &sembuf32);
    138 		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
    139 		    sizeof(sembuf32));
    140 	}
    141 
    142 	return (error);
    143 }
    144 #endif
    145 
    146 #if defined(SYSVMSG)
    147 
    148 int
    149 compat_50_netbsd32___msgctl13(struct lwp *l, const struct compat_50_netbsd32___msgctl13_args *uap, register_t *retval)
    150 {
    151 	/* {
    152 		syscallarg(int) msqid;
    153 		syscallarg(int) cmd;
    154 		syscallarg(netbsd32_msqid_ds50p_t) buf;
    155 	} */
    156 	struct msqid_ds ds;
    157 	struct netbsd32_msqid_ds50 ds32;
    158 	int error, cmd;
    159 
    160 	cmd = SCARG(uap, cmd);
    161 	if (cmd == IPC_SET) {
    162 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
    163 		if (error)
    164 			return error;
    165 		netbsd32_to_msqid_ds50(&ds32, &ds);
    166 	}
    167 
    168 	error = msgctl1(l, SCARG(uap, msqid), cmd,
    169 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
    170 
    171 	if (error == 0 && cmd == IPC_STAT) {
    172 		netbsd32_from_msqid_ds50(&ds, &ds32);
    173 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
    174 	}
    175 
    176 	return error;
    177 }
    178 #endif
    179 
    180 #if defined(SYSVSHM)
    181 
    182 int
    183 compat_50_netbsd32___shmctl13(struct lwp *l, const struct compat_50_netbsd32___shmctl13_args *uap, register_t *retval)
    184 {
    185 	/* {
    186 		syscallarg(int) shmid;
    187 		syscallarg(int) cmd;
    188 		syscallarg(netbsd32_shmid_ds50p_t) buf;
    189 	} */
    190 	struct shmid_ds ds;
    191 	struct netbsd32_shmid_ds50 ds32;
    192 	int error, cmd;
    193 
    194 	cmd = SCARG(uap, cmd);
    195 	if (cmd == IPC_SET) {
    196 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
    197 		if (error)
    198 			return error;
    199 		netbsd32_to_shmid_ds50(&ds32, &ds);
    200 	}
    201 
    202 	error = shmctl1(l, SCARG(uap, shmid), cmd,
    203 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
    204 
    205 	if (error == 0 && cmd == IPC_STAT) {
    206 		netbsd32_from_shmid_ds50(&ds, &ds32);
    207 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
    208 	}
    209 
    210 	return error;
    211 }
    212 #endif
    213 
    214 #define _PKG_ENTRY(name)        \
    215 	{ NETBSD32_SYS_ ## name, 0, (sy_call_t *)name }
    216 
    217 static const struct syscall_package compat_sysvipc_50_syscalls[] = {
    218 #if defined(SYSVSEM)
    219 	_PKG_ENTRY(compat_50_netbsd32___semctl14),
    220 #endif
    221 #if defined(SYSVSHM)
    222 	_PKG_ENTRY(compat_50_netbsd32___shmctl13),
    223 #endif
    224 #if defined(SYSVMSG)
    225 	_PKG_ENTRY(compat_50_netbsd32___msgctl13),
    226 #endif
    227 	{ 0, 0, NULL }
    228 };
    229 
    230 #define REQ1    "sysv_ipc,compat_sysv_50,"
    231 #define REQ2    "compat_netbsd32,compat_netbsd32_sysvipc,"
    232 
    233 MODULE(MODULE_CLASS_EXEC, compat_netbsd32_sysvipc_50, REQ1 REQ2);
    234 
    235 static int
    236 compat_netbsd32_sysvipc_50_modcmd(modcmd_t cmd, void *arg)
    237 {
    238 
    239         switch (cmd) {
    240         case MODULE_CMD_INIT:
    241                 return syscall_establish(&emul_netbsd32,
    242                     compat_sysvipc_50_syscalls);
    243 
    244         case MODULE_CMD_FINI:
    245                 return syscall_disestablish(&emul_netbsd32,
    246                     compat_sysvipc_50_syscalls);
    247 
    248         default:
    249                 return ENOTTY;
    250         }
    251 }
    252 
    253 #endif /* COMPAT_50 */
    254