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 */ 219acbbeafSnn /* 22*80e2ca85S * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 239acbbeafSnn */ 249acbbeafSnn 259acbbeafSnn #include <sys/errno.h> 269acbbeafSnn #include <sys/exec.h> 279acbbeafSnn #include <sys/kmem.h> 289acbbeafSnn #include <sys/modctl.h> 299acbbeafSnn #include <sys/model.h> 309acbbeafSnn #include <sys/proc.h> 319acbbeafSnn #include <sys/syscall.h> 329acbbeafSnn #include <sys/systm.h> 339acbbeafSnn #include <sys/thread.h> 349acbbeafSnn #include <sys/cmn_err.h> 359acbbeafSnn #include <sys/archsystm.h> 36628e3cbeSEdward Pilatowicz #include <sys/pathname.h> 379acbbeafSnn 389acbbeafSnn #include <sys/machbrand.h> 399acbbeafSnn #include <sys/brand.h> 409acbbeafSnn #include "sn1_brand.h" 419acbbeafSnn 429acbbeafSnn char *sn1_emulation_table = NULL; 439acbbeafSnn 44319378d9Seh void sn1_init_brand_data(zone_t *); 45319378d9Seh void sn1_free_brand_data(zone_t *); 469acbbeafSnn void sn1_setbrand(proc_t *); 479acbbeafSnn int sn1_getattr(zone_t *, int, void *, size_t *); 489acbbeafSnn int sn1_setattr(zone_t *, int, void *, size_t); 499acbbeafSnn int sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t, 509acbbeafSnn uintptr_t, uintptr_t, uintptr_t); 519acbbeafSnn void sn1_copy_procdata(proc_t *, proc_t *); 529acbbeafSnn void sn1_proc_exit(struct proc *, klwp_t *); 539acbbeafSnn void sn1_exec(); 549acbbeafSnn int sn1_initlwp(klwp_t *); 559acbbeafSnn void sn1_forklwp(klwp_t *, klwp_t *); 569acbbeafSnn void sn1_freelwp(klwp_t *); 579acbbeafSnn void sn1_lwpexit(klwp_t *); 589acbbeafSnn int sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, 599acbbeafSnn long *, int, caddr_t, cred_t *, int); 609acbbeafSnn 619acbbeafSnn /* sn1 brand */ 629acbbeafSnn struct brand_ops sn1_brops = { 63319378d9Seh sn1_init_brand_data, 64319378d9Seh sn1_free_brand_data, 659acbbeafSnn sn1_brandsys, 669acbbeafSnn sn1_setbrand, 679acbbeafSnn sn1_getattr, 689acbbeafSnn sn1_setattr, 699acbbeafSnn sn1_copy_procdata, 709acbbeafSnn sn1_proc_exit, 719acbbeafSnn sn1_exec, 729acbbeafSnn lwp_setrval, 739acbbeafSnn sn1_initlwp, 749acbbeafSnn sn1_forklwp, 759acbbeafSnn sn1_freelwp, 769acbbeafSnn sn1_lwpexit, 77eb9dbf0cSRoger A. Faulkner sn1_elfexec, 788f798d3aSRoger A. Faulkner NULL, 798f798d3aSRoger A. Faulkner NULL, 808f798d3aSRoger A. Faulkner NSIG, 819acbbeafSnn }; 829acbbeafSnn 839acbbeafSnn #ifdef sparc 849acbbeafSnn 859acbbeafSnn struct brand_mach_ops sn1_mops = { 869acbbeafSnn sn1_brand_syscall_callback, 87628e3cbeSEdward Pilatowicz sn1_brand_syscall32_callback 889acbbeafSnn }; 899acbbeafSnn 909acbbeafSnn #else /* sparc */ 919acbbeafSnn 929acbbeafSnn #ifdef __amd64 939acbbeafSnn 949acbbeafSnn struct brand_mach_ops sn1_mops = { 959acbbeafSnn sn1_brand_sysenter_callback, 969acbbeafSnn NULL, 979acbbeafSnn sn1_brand_int91_callback, 989acbbeafSnn sn1_brand_syscall_callback, 999acbbeafSnn sn1_brand_syscall32_callback, 1009acbbeafSnn NULL 1019acbbeafSnn }; 1029acbbeafSnn 1039acbbeafSnn #else /* ! __amd64 */ 1049acbbeafSnn 1059acbbeafSnn struct brand_mach_ops sn1_mops = { 1069acbbeafSnn sn1_brand_sysenter_callback, 1079acbbeafSnn NULL, 1089acbbeafSnn NULL, 1099acbbeafSnn sn1_brand_syscall_callback, 1109acbbeafSnn NULL, 1119acbbeafSnn NULL 1129acbbeafSnn }; 1139acbbeafSnn #endif /* __amd64 */ 1149acbbeafSnn 1159acbbeafSnn #endif /* _sparc */ 1169acbbeafSnn 1179acbbeafSnn struct brand sn1_brand = { 1189acbbeafSnn BRAND_VER_1, 1199acbbeafSnn "sn1", 1209acbbeafSnn &sn1_brops, 1219acbbeafSnn &sn1_mops 1229acbbeafSnn }; 1239acbbeafSnn 1249acbbeafSnn static struct modlbrand modlbrand = { 125c6f42f0eSedp &mod_brandops, /* type of module */ 126c6f42f0eSedp "Solaris N-1 Brand", /* description of module */ 127c6f42f0eSedp &sn1_brand /* driver ops */ 1289acbbeafSnn }; 1299acbbeafSnn 1309acbbeafSnn static struct modlinkage modlinkage = { 1319acbbeafSnn MODREV_1, (void *)&modlbrand, NULL 1329acbbeafSnn }; 1339acbbeafSnn 1349acbbeafSnn void 1359acbbeafSnn sn1_setbrand(proc_t *p) 1369acbbeafSnn { 137*80e2ca85S brand_solaris_setbrand(p, &sn1_brand); 1389acbbeafSnn } 1399acbbeafSnn 1409acbbeafSnn /* ARGSUSED */ 1419acbbeafSnn int 1429acbbeafSnn sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize) 1439acbbeafSnn { 1449acbbeafSnn return (EINVAL); 1459acbbeafSnn } 1469acbbeafSnn 1479acbbeafSnn /* ARGSUSED */ 1489acbbeafSnn int 1499acbbeafSnn sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize) 1509acbbeafSnn { 1519acbbeafSnn return (EINVAL); 1529acbbeafSnn } 1539acbbeafSnn 1549acbbeafSnn /*ARGSUSED*/ 1559acbbeafSnn int 1569acbbeafSnn sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, 1579acbbeafSnn uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6) 1589acbbeafSnn { 159*80e2ca85S int res; 160628e3cbeSEdward Pilatowicz 1619acbbeafSnn *rval = 0; 1629acbbeafSnn 163*80e2ca85S res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &sn1_brand, SN1_VERSION); 164*80e2ca85S if (res >= 0) 165*80e2ca85S return (res); 1669acbbeafSnn 1679acbbeafSnn return (EINVAL); 1689acbbeafSnn } 1699acbbeafSnn 1709acbbeafSnn void 1719acbbeafSnn sn1_copy_procdata(proc_t *child, proc_t *parent) 1729acbbeafSnn { 173*80e2ca85S brand_solaris_copy_procdata(child, parent, &sn1_brand); 1749acbbeafSnn } 1759acbbeafSnn 1769acbbeafSnn void 1779acbbeafSnn sn1_proc_exit(struct proc *p, klwp_t *l) 1789acbbeafSnn { 179*80e2ca85S brand_solaris_proc_exit(p, l, &sn1_brand); 1809acbbeafSnn } 1819acbbeafSnn 1829acbbeafSnn void 1839acbbeafSnn sn1_exec() 1849acbbeafSnn { 185*80e2ca85S brand_solaris_exec(&sn1_brand); 1869acbbeafSnn } 1879acbbeafSnn 1889acbbeafSnn int 1899acbbeafSnn sn1_initlwp(klwp_t *l) 1909acbbeafSnn { 191*80e2ca85S return (brand_solaris_initlwp(l, &sn1_brand)); 1929acbbeafSnn } 1939acbbeafSnn 194319378d9Seh void 195fd9e7635Sedp sn1_forklwp(klwp_t *p, klwp_t *c) 196319378d9Seh { 197*80e2ca85S brand_solaris_forklwp(p, c, &sn1_brand); 198319378d9Seh } 199319378d9Seh 200319378d9Seh void 201fd9e7635Sedp sn1_freelwp(klwp_t *l) 202319378d9Seh { 203*80e2ca85S brand_solaris_freelwp(l, &sn1_brand); 204319378d9Seh } 205319378d9Seh 2069acbbeafSnn void 207fd9e7635Sedp sn1_lwpexit(klwp_t *l) 2089acbbeafSnn { 209*80e2ca85S brand_solaris_lwpexit(l, &sn1_brand); 2109acbbeafSnn } 2119acbbeafSnn 2129acbbeafSnn /*ARGSUSED*/ 2139acbbeafSnn void 214628e3cbeSEdward Pilatowicz sn1_free_brand_data(zone_t *zone) 2159acbbeafSnn { 2169acbbeafSnn } 2179acbbeafSnn 2189acbbeafSnn /*ARGSUSED*/ 2199acbbeafSnn void 220628e3cbeSEdward Pilatowicz sn1_init_brand_data(zone_t *zone) 221628e3cbeSEdward Pilatowicz { 222628e3cbeSEdward Pilatowicz } 223628e3cbeSEdward Pilatowicz 2249acbbeafSnn int 2259acbbeafSnn sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap, 2269acbbeafSnn int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred, 2279acbbeafSnn int brand_action) 2289acbbeafSnn { 229*80e2ca85S return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz, 230*80e2ca85S setid, exec_file, cred, brand_action, &sn1_brand, SN1_BRANDNAME, 231*80e2ca85S SN1_LIB, SN1_LIB32, SN1_LINKER, SN1_LINKER32)); 2329acbbeafSnn } 2339acbbeafSnn 2349acbbeafSnn int 2359acbbeafSnn _init(void) 2369acbbeafSnn { 2379acbbeafSnn int err; 2389acbbeafSnn 2399acbbeafSnn /* 2409acbbeafSnn * Set up the table indicating which system calls we want to 2419acbbeafSnn * interpose on. We should probably build this automatically from 2429acbbeafSnn * a list of system calls that is shared with the user-space 2439acbbeafSnn * library. 2449acbbeafSnn */ 2459acbbeafSnn sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP); 246628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_read] = 1; /* 3 */ 247628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_write] = 1; /* 4 */ 248628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_time] = 1; /* 13 */ 249628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_getpid] = 1; /* 20 */ 250628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_mount] = 1; /* 21 */ 251628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_getuid] = 1; /* 24 */ 252628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_times] = 1; /* 43 */ 253628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_getgid] = 1; /* 47 */ 254628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_utssys] = 1; /* 57 */ 255628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_readlink] = 1; /* 90 */ 2568fd04b83SRoger A. Faulkner sn1_emulation_table[SYS_waitid] = 1; /* 107 */ 257628e3cbeSEdward Pilatowicz sn1_emulation_table[SYS_uname] = 1; /* 135 */ 2589acbbeafSnn 2599acbbeafSnn err = mod_install(&modlinkage); 2609acbbeafSnn if (err) { 2619acbbeafSnn cmn_err(CE_WARN, "Couldn't install brand module"); 2629acbbeafSnn kmem_free(sn1_emulation_table, NSYSCALL); 2639acbbeafSnn } 2649acbbeafSnn 2659acbbeafSnn return (err); 2669acbbeafSnn } 2679acbbeafSnn 2689acbbeafSnn int 2699acbbeafSnn _info(struct modinfo *modinfop) 2709acbbeafSnn { 2719acbbeafSnn return (mod_info(&modlinkage, modinfop)); 2729acbbeafSnn } 2739acbbeafSnn 2749acbbeafSnn int 2759acbbeafSnn _fini(void) 2769acbbeafSnn { 277*80e2ca85S return (brand_solaris_fini(&sn1_emulation_table, &modlinkage, 278*80e2ca85S &sn1_brand)); 2799acbbeafSnn } 280