19acbbeafSnn /*
29acbbeafSnn  * CDDL HEADER START
39acbbeafSnn  *
49acbbeafSnn  * The contents of this file are subject to the terms of the
59acbbeafSnn  * Common Development and Distribution License (the "License").
69acbbeafSnn  * You may not use this file except in compliance with the License.
79acbbeafSnn  *
89acbbeafSnn  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99acbbeafSnn  * or http://www.opensolaris.org/os/licensing.
109acbbeafSnn  * See the License for the specific language governing permissions
119acbbeafSnn  * and limitations under the License.
129acbbeafSnn  *
139acbbeafSnn  * When distributing Covered Code, include this CDDL HEADER in each
149acbbeafSnn  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159acbbeafSnn  * If applicable, add the following below this CDDL HEADER, with the
169acbbeafSnn  * fields enclosed by brackets "[]" replaced with your own identifying
179acbbeafSnn  * information: Portions Copyright [yyyy] [name of copyright owner]
189acbbeafSnn  *
199acbbeafSnn  * CDDL HEADER END
209acbbeafSnn  */
21*794f0adbSRoger A. Faulkner 
229acbbeafSnn /*
2380e2ca85S  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
249acbbeafSnn  */
259acbbeafSnn 
269acbbeafSnn #include <sys/errno.h>
279acbbeafSnn #include <sys/exec.h>
289acbbeafSnn #include <sys/kmem.h>
299acbbeafSnn #include <sys/modctl.h>
309acbbeafSnn #include <sys/model.h>
319acbbeafSnn #include <sys/proc.h>
329acbbeafSnn #include <sys/syscall.h>
339acbbeafSnn #include <sys/systm.h>
349acbbeafSnn #include <sys/thread.h>
359acbbeafSnn #include <sys/cmn_err.h>
369acbbeafSnn #include <sys/archsystm.h>
37628e3cbeSEdward Pilatowicz #include <sys/pathname.h>
389acbbeafSnn 
399acbbeafSnn #include <sys/machbrand.h>
409acbbeafSnn #include <sys/brand.h>
419acbbeafSnn #include "sn1_brand.h"
429acbbeafSnn 
439acbbeafSnn char *sn1_emulation_table = NULL;
449acbbeafSnn 
45319378d9Seh void	sn1_init_brand_data(zone_t *);
46319378d9Seh void	sn1_free_brand_data(zone_t *);
479acbbeafSnn void	sn1_setbrand(proc_t *);
489acbbeafSnn int	sn1_getattr(zone_t *, int, void *, size_t *);
499acbbeafSnn int	sn1_setattr(zone_t *, int, void *, size_t);
509acbbeafSnn int	sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
519acbbeafSnn 		uintptr_t, uintptr_t, uintptr_t);
529acbbeafSnn void	sn1_copy_procdata(proc_t *, proc_t *);
539acbbeafSnn void	sn1_proc_exit(struct proc *, klwp_t *);
549acbbeafSnn void	sn1_exec();
559acbbeafSnn int	sn1_initlwp(klwp_t *);
569acbbeafSnn void	sn1_forklwp(klwp_t *, klwp_t *);
579acbbeafSnn void	sn1_freelwp(klwp_t *);
589acbbeafSnn void	sn1_lwpexit(klwp_t *);
599acbbeafSnn int	sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
609acbbeafSnn 	long *, int, caddr_t, cred_t *, int);
619acbbeafSnn 
629acbbeafSnn /* sn1 brand */
639acbbeafSnn struct brand_ops sn1_brops = {
64319378d9Seh 	sn1_init_brand_data,
65319378d9Seh 	sn1_free_brand_data,
669acbbeafSnn 	sn1_brandsys,
679acbbeafSnn 	sn1_setbrand,
689acbbeafSnn 	sn1_getattr,
699acbbeafSnn 	sn1_setattr,
709acbbeafSnn 	sn1_copy_procdata,
719acbbeafSnn 	sn1_proc_exit,
729acbbeafSnn 	sn1_exec,
739acbbeafSnn 	lwp_setrval,
749acbbeafSnn 	sn1_initlwp,
759acbbeafSnn 	sn1_forklwp,
769acbbeafSnn 	sn1_freelwp,
779acbbeafSnn 	sn1_lwpexit,
78eb9dbf0cSRoger A. Faulkner 	sn1_elfexec,
798f798d3aSRoger A. Faulkner 	NULL,
808f798d3aSRoger A. Faulkner 	NULL,
818f798d3aSRoger A. Faulkner 	NSIG,
829acbbeafSnn };
839acbbeafSnn 
849acbbeafSnn #ifdef	sparc
859acbbeafSnn 
869acbbeafSnn struct brand_mach_ops sn1_mops = {
879acbbeafSnn 	sn1_brand_syscall_callback,
88628e3cbeSEdward Pilatowicz 	sn1_brand_syscall32_callback
899acbbeafSnn };
909acbbeafSnn 
919acbbeafSnn #else	/* sparc */
929acbbeafSnn 
939acbbeafSnn #ifdef	__amd64
949acbbeafSnn 
959acbbeafSnn struct brand_mach_ops sn1_mops = {
969acbbeafSnn 	sn1_brand_sysenter_callback,
979acbbeafSnn 	sn1_brand_int91_callback,
989acbbeafSnn 	sn1_brand_syscall_callback,
99eb5a5c78SSurya Prakki 	sn1_brand_syscall32_callback
1009acbbeafSnn };
1019acbbeafSnn 
1029acbbeafSnn #else	/* ! __amd64 */
1039acbbeafSnn 
1049acbbeafSnn struct brand_mach_ops sn1_mops = {
1059acbbeafSnn 	sn1_brand_sysenter_callback,
1069acbbeafSnn 	NULL,
1079acbbeafSnn 	sn1_brand_syscall_callback,
1089acbbeafSnn 	NULL
1099acbbeafSnn };
1109acbbeafSnn #endif	/* __amd64 */
1119acbbeafSnn 
1129acbbeafSnn #endif	/* _sparc */
1139acbbeafSnn 
1149acbbeafSnn struct brand	sn1_brand = {
1159acbbeafSnn 	BRAND_VER_1,
1169acbbeafSnn 	"sn1",
1179acbbeafSnn 	&sn1_brops,
1189acbbeafSnn 	&sn1_mops
1199acbbeafSnn };
1209acbbeafSnn 
1219acbbeafSnn static struct modlbrand modlbrand = {
122c6f42f0eSedp 	&mod_brandops,		/* type of module */
123c6f42f0eSedp 	"Solaris N-1 Brand",	/* description of module */
124c6f42f0eSedp 	&sn1_brand		/* driver ops */
1259acbbeafSnn };
1269acbbeafSnn 
1279acbbeafSnn static struct modlinkage modlinkage = {
1289acbbeafSnn 	MODREV_1, (void *)&modlbrand, NULL
1299acbbeafSnn };
1309acbbeafSnn 
1319acbbeafSnn void
sn1_setbrand(proc_t * p)1329acbbeafSnn sn1_setbrand(proc_t *p)
1339acbbeafSnn {
13480e2ca85S 	brand_solaris_setbrand(p, &sn1_brand);
1359acbbeafSnn }
1369acbbeafSnn 
1379acbbeafSnn /* ARGSUSED */
1389acbbeafSnn int
sn1_getattr(zone_t * zone,int attr,void * buf,size_t * bufsize)1399acbbeafSnn sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
1409acbbeafSnn {
1419acbbeafSnn 	return (EINVAL);
1429acbbeafSnn }
1439acbbeafSnn 
1449acbbeafSnn /* ARGSUSED */
1459acbbeafSnn int
sn1_setattr(zone_t * zone,int attr,void * buf,size_t bufsize)1469acbbeafSnn sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
1479acbbeafSnn {
1489acbbeafSnn 	return (EINVAL);
1499acbbeafSnn }
1509acbbeafSnn 
1519acbbeafSnn /*ARGSUSED*/
1529acbbeafSnn int
sn1_brandsys(int cmd,int64_t * rval,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t arg6)1539acbbeafSnn sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
1549acbbeafSnn     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
1559acbbeafSnn {
15680e2ca85S 	int	res;
157628e3cbeSEdward Pilatowicz 
1589acbbeafSnn 	*rval = 0;
1599acbbeafSnn 
16080e2ca85S 	res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &sn1_brand, SN1_VERSION);
16180e2ca85S 	if (res >= 0)
16280e2ca85S 		return (res);
1639acbbeafSnn 
1649acbbeafSnn 	return (EINVAL);
1659acbbeafSnn }
1669acbbeafSnn 
1679acbbeafSnn void
sn1_copy_procdata(proc_t * child,proc_t * parent)1689acbbeafSnn sn1_copy_procdata(proc_t *child, proc_t *parent)
1699acbbeafSnn {
17080e2ca85S 	brand_solaris_copy_procdata(child, parent, &sn1_brand);
1719acbbeafSnn }
1729acbbeafSnn 
1739acbbeafSnn void
sn1_proc_exit(struct proc * p,klwp_t * l)1749acbbeafSnn sn1_proc_exit(struct proc *p, klwp_t *l)
1759acbbeafSnn {
17680e2ca85S 	brand_solaris_proc_exit(p, l, &sn1_brand);
1779acbbeafSnn }
1789acbbeafSnn 
1799acbbeafSnn void
sn1_exec()1809acbbeafSnn sn1_exec()
1819acbbeafSnn {
18280e2ca85S 	brand_solaris_exec(&sn1_brand);
1839acbbeafSnn }
1849acbbeafSnn 
1859acbbeafSnn int
sn1_initlwp(klwp_t * l)1869acbbeafSnn sn1_initlwp(klwp_t *l)
1879acbbeafSnn {
18880e2ca85S 	return (brand_solaris_initlwp(l, &sn1_brand));
1899acbbeafSnn }
1909acbbeafSnn 
191319378d9Seh void
sn1_forklwp(klwp_t * p,klwp_t * c)192fd9e7635Sedp sn1_forklwp(klwp_t *p, klwp_t *c)
193319378d9Seh {
19480e2ca85S 	brand_solaris_forklwp(p, c, &sn1_brand);
195319378d9Seh }
196319378d9Seh 
197319378d9Seh void
sn1_freelwp(klwp_t * l)198fd9e7635Sedp sn1_freelwp(klwp_t *l)
199319378d9Seh {
20080e2ca85S 	brand_solaris_freelwp(l, &sn1_brand);
201319378d9Seh }
202319378d9Seh 
2039acbbeafSnn void
sn1_lwpexit(klwp_t * l)204fd9e7635Sedp sn1_lwpexit(klwp_t *l)
2059acbbeafSnn {
20680e2ca85S 	brand_solaris_lwpexit(l, &sn1_brand);
2079acbbeafSnn }
2089acbbeafSnn 
2099acbbeafSnn /*ARGSUSED*/
2109acbbeafSnn void
sn1_free_brand_data(zone_t * zone)211628e3cbeSEdward Pilatowicz sn1_free_brand_data(zone_t *zone)
2129acbbeafSnn {
2139acbbeafSnn }
2149acbbeafSnn 
2159acbbeafSnn /*ARGSUSED*/
2169acbbeafSnn void
sn1_init_brand_data(zone_t * zone)217628e3cbeSEdward Pilatowicz sn1_init_brand_data(zone_t *zone)
218628e3cbeSEdward Pilatowicz {
219628e3cbeSEdward Pilatowicz }
220628e3cbeSEdward Pilatowicz 
2219acbbeafSnn int
sn1_elfexec(vnode_t * vp,execa_t * uap,uarg_t * args,intpdata_t * idatap,int level,long * execsz,int setid,caddr_t exec_file,cred_t * cred,int brand_action)2229acbbeafSnn sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
2239acbbeafSnn 	int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
2249acbbeafSnn 	int brand_action)
2259acbbeafSnn {
22680e2ca85S 	return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
22780e2ca85S 	    setid, exec_file, cred, brand_action, &sn1_brand, SN1_BRANDNAME,
22880e2ca85S 	    SN1_LIB, SN1_LIB32, SN1_LINKER, SN1_LINKER32));
2299acbbeafSnn }
2309acbbeafSnn 
2319acbbeafSnn int
_init(void)2329acbbeafSnn _init(void)
2339acbbeafSnn {
2349acbbeafSnn 	int err;
2359acbbeafSnn 
2369acbbeafSnn 	/*
2379acbbeafSnn 	 * Set up the table indicating which system calls we want to
2389acbbeafSnn 	 * interpose on.  We should probably build this automatically from
2399acbbeafSnn 	 * a list of system calls that is shared with the user-space
2409acbbeafSnn 	 * library.
2419acbbeafSnn 	 */
2429acbbeafSnn 	sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
243628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_read] = 1;			/*   3 */
244628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_write] = 1;			/*   4 */
245628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_time] = 1;			/*  13 */
246628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getpid] = 1;			/*  20 */
247628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_mount] = 1;			/*  21 */
248628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getuid] = 1;			/*  24 */
249628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_times] = 1;			/*  43 */
250628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getgid] = 1;			/*  47 */
251628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_utssys] = 1;			/*  57 */
2528fd04b83SRoger A. Faulkner 	sn1_emulation_table[SYS_waitid] = 1;			/* 107 */
253628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_uname] = 1;			/* 135 */
2549acbbeafSnn 
2559acbbeafSnn 	err = mod_install(&modlinkage);
2569acbbeafSnn 	if (err) {
2579acbbeafSnn 		cmn_err(CE_WARN, "Couldn't install brand module");
2589acbbeafSnn 		kmem_free(sn1_emulation_table, NSYSCALL);
2599acbbeafSnn 	}
2609acbbeafSnn 
2619acbbeafSnn 	return (err);
2629acbbeafSnn }
2639acbbeafSnn 
2649acbbeafSnn int
_info(struct modinfo * modinfop)2659acbbeafSnn _info(struct modinfo *modinfop)
2669acbbeafSnn {
2679acbbeafSnn 	return (mod_info(&modlinkage, modinfop));
2689acbbeafSnn }
2699acbbeafSnn 
2709acbbeafSnn int
_fini(void)2719acbbeafSnn _fini(void)
2729acbbeafSnn {
27380e2ca85S 	return (brand_solaris_fini(&sn1_emulation_table, &modlinkage,
27480e2ca85S 	    &sn1_brand));
2759acbbeafSnn }
276