Home | History | Annotate | Download | only in sn1
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/errno.h>
     27 #include <sys/exec.h>
     28 #include <sys/kmem.h>
     29 #include <sys/modctl.h>
     30 #include <sys/model.h>
     31 #include <sys/proc.h>
     32 #include <sys/syscall.h>
     33 #include <sys/systm.h>
     34 #include <sys/thread.h>
     35 #include <sys/cmn_err.h>
     36 #include <sys/archsystm.h>
     37 #include <sys/pathname.h>
     38 
     39 #include <sys/machbrand.h>
     40 #include <sys/brand.h>
     41 #include "sn1_brand.h"
     42 
     43 char *sn1_emulation_table = NULL;
     44 
     45 void	sn1_init_brand_data(zone_t *);
     46 void	sn1_free_brand_data(zone_t *);
     47 void	sn1_setbrand(proc_t *);
     48 int	sn1_getattr(zone_t *, int, void *, size_t *);
     49 int	sn1_setattr(zone_t *, int, void *, size_t);
     50 int	sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
     51 		uintptr_t, uintptr_t, uintptr_t);
     52 void	sn1_copy_procdata(proc_t *, proc_t *);
     53 void	sn1_proc_exit(struct proc *, klwp_t *);
     54 void	sn1_exec();
     55 int	sn1_initlwp(klwp_t *);
     56 void	sn1_forklwp(klwp_t *, klwp_t *);
     57 void	sn1_freelwp(klwp_t *);
     58 void	sn1_lwpexit(klwp_t *);
     59 int	sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
     60 	long *, int, caddr_t, cred_t *, int);
     61 
     62 /* sn1 brand */
     63 struct brand_ops sn1_brops = {
     64 	sn1_init_brand_data,
     65 	sn1_free_brand_data,
     66 	sn1_brandsys,
     67 	sn1_setbrand,
     68 	sn1_getattr,
     69 	sn1_setattr,
     70 	sn1_copy_procdata,
     71 	sn1_proc_exit,
     72 	sn1_exec,
     73 	lwp_setrval,
     74 	sn1_initlwp,
     75 	sn1_forklwp,
     76 	sn1_freelwp,
     77 	sn1_lwpexit,
     78 	sn1_elfexec
     79 };
     80 
     81 #ifdef	sparc
     82 
     83 struct brand_mach_ops sn1_mops = {
     84 	sn1_brand_syscall_callback,
     85 	sn1_brand_syscall32_callback
     86 };
     87 
     88 #else	/* sparc */
     89 
     90 #ifdef	__amd64
     91 
     92 struct brand_mach_ops sn1_mops = {
     93 	sn1_brand_sysenter_callback,
     94 	NULL,
     95 	sn1_brand_int91_callback,
     96 	sn1_brand_syscall_callback,
     97 	sn1_brand_syscall32_callback,
     98 	NULL
     99 };
    100 
    101 #else	/* ! __amd64 */
    102 
    103 struct brand_mach_ops sn1_mops = {
    104 	sn1_brand_sysenter_callback,
    105 	NULL,
    106 	NULL,
    107 	sn1_brand_syscall_callback,
    108 	NULL,
    109 	NULL
    110 };
    111 #endif	/* __amd64 */
    112 
    113 #endif	/* _sparc */
    114 
    115 struct brand	sn1_brand = {
    116 	BRAND_VER_1,
    117 	"sn1",
    118 	&sn1_brops,
    119 	&sn1_mops
    120 };
    121 
    122 static struct modlbrand modlbrand = {
    123 	&mod_brandops,		/* type of module */
    124 	"Solaris N-1 Brand",	/* description of module */
    125 	&sn1_brand		/* driver ops */
    126 };
    127 
    128 static struct modlinkage modlinkage = {
    129 	MODREV_1, (void *)&modlbrand, NULL
    130 };
    131 
    132 void
    133 sn1_setbrand(proc_t *p)
    134 {
    135 	ASSERT(p->p_brand == &sn1_brand);
    136 	ASSERT(p->p_brand_data == NULL);
    137 
    138 	/*
    139 	 * We should only be called from exec(), when we know the process
    140 	 * is single-threaded.
    141 	 */
    142 	ASSERT(p->p_tlist == p->p_tlist->t_forw);
    143 
    144 	p->p_brand_data = kmem_zalloc(sizeof (sn1_proc_data_t), KM_SLEEP);
    145 	(void) sn1_initlwp(p->p_tlist->t_lwp);
    146 }
    147 
    148 /* ARGSUSED */
    149 int
    150 sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
    151 {
    152 	return (EINVAL);
    153 }
    154 
    155 /* ARGSUSED */
    156 int
    157 sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
    158 {
    159 	return (EINVAL);
    160 }
    161 
    162 /*
    163  * Get the address of the user-space system call handler from the user
    164  * process and attach it to the proc structure.
    165  */
    166 /*ARGSUSED*/
    167 int
    168 sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
    169     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
    170 {
    171 	sn1_proc_data_t	*spd;
    172 	sn1_brand_reg_t	reg;
    173 	proc_t		*p = curproc;
    174 	int		err;
    175 
    176 	*rval = 0;
    177 
    178 	/*
    179 	 * There is one operation that is suppored for non-branded
    180 	 * process.  B_EXEC_BRAND.  This brand operaion is redundant
    181 	 * since the kernel assumes a native process doing an exec
    182 	 * in a branded zone is going to run a branded processes.
    183 	 * hence we don't support this operation.
    184 	 */
    185 	if (cmd == B_EXEC_BRAND)
    186 		return (ENOSYS);
    187 
    188 	/* For all other operations this must be a branded process. */
    189 	if (p->p_brand == &native_brand)
    190 		return (ENOSYS);
    191 
    192 	ASSERT(p->p_brand == &sn1_brand);
    193 	ASSERT(p->p_brand_data != NULL);
    194 
    195 	spd = (sn1_proc_data_t *)p->p_brand_data;
    196 
    197 	switch (cmd) {
    198 	case B_EXEC_NATIVE:
    199 		err = exec_common(
    200 		    (char *)arg1, (const char **)arg2, (const char **)arg3,
    201 		    EBA_NATIVE);
    202 		return (err);
    203 
    204 	case B_REGISTER:
    205 		if (p->p_model == DATAMODEL_NATIVE) {
    206 			if (copyin((void *)arg1, &reg, sizeof (reg)) != 0)
    207 				return (EFAULT);
    208 #if defined(_LP64)
    209 		} else {
    210 			sn1_brand_reg32_t reg32;
    211 
    212 			if (copyin((void *)arg1, &reg32, sizeof (reg32)) != 0)
    213 				return (EFAULT);
    214 			reg.sbr_version = reg32.sbr_version;
    215 			reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
    216 #endif /* _LP64 */
    217 		}
    218 
    219 		if (reg.sbr_version != SN1_VERSION)
    220 			return (ENOTSUP);
    221 		spd->spd_handler = reg.sbr_handler;
    222 		return (0);
    223 	case B_ELFDATA:
    224 		if (p->p_model == DATAMODEL_NATIVE) {
    225 			if (copyout(&spd->spd_elf_data, (void *)arg1,
    226 			    sizeof (sn1_elf_data_t)) != 0)
    227 				return (EFAULT);
    228 #if defined(_LP64)
    229 		} else {
    230 			sn1_elf_data32_t sed32;
    231 
    232 			sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
    233 			sed32.sed_phent = spd->spd_elf_data.sed_phent;
    234 			sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
    235 			sed32.sed_entry = spd->spd_elf_data.sed_entry;
    236 			sed32.sed_base = spd->spd_elf_data.sed_base;
    237 			sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
    238 			sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
    239 			if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0)
    240 				return (EFAULT);
    241 #endif /* _LP64 */
    242 		}
    243 		return (0);
    244 	}
    245 
    246 	return (EINVAL);
    247 }
    248 
    249 /*
    250  * Copy the per-process brand data from a parent proc to a child.
    251  */
    252 void
    253 sn1_copy_procdata(proc_t *child, proc_t *parent)
    254 {
    255 	sn1_proc_data_t	*spd;
    256 
    257 	ASSERT(parent->p_brand == &sn1_brand);
    258 	ASSERT(child->p_brand == &sn1_brand);
    259 	ASSERT(parent->p_brand_data != NULL);
    260 	ASSERT(child->p_brand_data == NULL);
    261 
    262 	/* Just duplicate all the proc data of the parent for the child */
    263 	spd = kmem_alloc(sizeof (sn1_proc_data_t), KM_SLEEP);
    264 	bcopy(parent->p_brand_data, spd, sizeof (sn1_proc_data_t));
    265 	child->p_brand_data = spd;
    266 }
    267 
    268 /*ARGSUSED*/
    269 void
    270 sn1_proc_exit(struct proc *p, klwp_t *l)
    271 {
    272 	ASSERT(p->p_brand == &sn1_brand);
    273 	ASSERT(p->p_brand_data != NULL);
    274 
    275 	/*
    276 	 * We should only be called from proc_exit(), when we know that
    277 	 * process is single-threaded.
    278 	 */
    279 	ASSERT(p->p_tlist == p->p_tlist->t_forw);
    280 
    281 	/* upon exit, free our lwp brand data */
    282 	(void) sn1_freelwp(ttolwp(curthread));
    283 
    284 	/* upon exit, free our proc brand data */
    285 	kmem_free(p->p_brand_data, sizeof (sn1_proc_data_t));
    286 	p->p_brand_data = NULL;
    287 }
    288 
    289 void
    290 sn1_exec()
    291 {
    292 	sn1_proc_data_t	*spd = curproc->p_brand_data;
    293 
    294 	ASSERT(curproc->p_brand == &sn1_brand);
    295 	ASSERT(curproc->p_brand_data != NULL);
    296 	ASSERT(ttolwp(curthread)->lwp_brand != NULL);
    297 
    298 	/*
    299 	 * We should only be called from exec(), when we know the process
    300 	 * is single-threaded.
    301 	 */
    302 	ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
    303 
    304 	/* Upon exec, reset our lwp brand data. */
    305 	(void) sn1_freelwp(ttolwp(curthread));
    306 	(void) sn1_initlwp(ttolwp(curthread));
    307 
    308 	/*
    309 	 * Upon exec, reset all the proc brand data, except for the elf
    310 	 * data associated with the executable we are exec'ing.
    311 	 */
    312 	spd->spd_handler = NULL;
    313 }
    314 
    315 /*ARGSUSED*/
    316 int
    317 sn1_initlwp(klwp_t *l)
    318 {
    319 	ASSERT(l->lwp_procp->p_brand == &sn1_brand);
    320 	ASSERT(l->lwp_procp->p_brand_data != NULL);
    321 	ASSERT(l->lwp_brand == NULL);
    322 	l->lwp_brand = (void *)-1;
    323 	return (0);
    324 }
    325 
    326 /*ARGSUSED*/
    327 void
    328 sn1_forklwp(klwp_t *p, klwp_t *c)
    329 {
    330 	ASSERT(p->lwp_procp->p_brand == &sn1_brand);
    331 	ASSERT(c->lwp_procp->p_brand == &sn1_brand);
    332 
    333 	ASSERT(p->lwp_procp->p_brand_data != NULL);
    334 	ASSERT(c->lwp_procp->p_brand_data != NULL);
    335 
    336 	/* Both LWPs have already had been initialized via sn1_initlwp() */
    337 	ASSERT(p->lwp_brand != NULL);
    338 	ASSERT(c->lwp_brand != NULL);
    339 }
    340 
    341 /*ARGSUSED*/
    342 void
    343 sn1_freelwp(klwp_t *l)
    344 {
    345 	ASSERT(l->lwp_procp->p_brand == &sn1_brand);
    346 	ASSERT(l->lwp_procp->p_brand_data != NULL);
    347 	ASSERT(l->lwp_brand != NULL);
    348 	l->lwp_brand = NULL;
    349 }
    350 
    351 /*ARGSUSED*/
    352 void
    353 sn1_lwpexit(klwp_t *l)
    354 {
    355 	proc_t	*p = l->lwp_procp;
    356 
    357 	ASSERT(l->lwp_procp->p_brand == &sn1_brand);
    358 	ASSERT(l->lwp_procp->p_brand_data != NULL);
    359 	ASSERT(l->lwp_brand != NULL);
    360 
    361 	/*
    362 	 * We should never be called for the last thread in a process.
    363 	 * (That case is handled by sn1_proc_exit().)  There for this lwp
    364 	 * must be exiting from a multi-threaded process.
    365 	 */
    366 	ASSERT(p->p_tlist != p->p_tlist->t_forw);
    367 
    368 	l->lwp_brand = NULL;
    369 }
    370 
    371 /*ARGSUSED*/
    372 void
    373 sn1_free_brand_data(zone_t *zone)
    374 {
    375 }
    376 
    377 /*ARGSUSED*/
    378 void
    379 sn1_init_brand_data(zone_t *zone)
    380 {
    381 }
    382 
    383 #if defined(_LP64)
    384 static void
    385 Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst)
    386 {
    387 	bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
    388 	dst->e_type =		src->e_type;
    389 	dst->e_machine =	src->e_machine;
    390 	dst->e_version =	src->e_version;
    391 	dst->e_entry =		src->e_entry;
    392 	dst->e_phoff =		src->e_phoff;
    393 	dst->e_shoff =		src->e_shoff;
    394 	dst->e_flags =		src->e_flags;
    395 	dst->e_ehsize =		src->e_ehsize;
    396 	dst->e_phentsize =	src->e_phentsize;
    397 	dst->e_phnum =		src->e_phnum;
    398 	dst->e_shentsize =	src->e_shentsize;
    399 	dst->e_shnum =		src->e_shnum;
    400 	dst->e_shstrndx =	src->e_shstrndx;
    401 }
    402 #endif /* _LP64 */
    403 
    404 int
    405 sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
    406 	int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
    407 	int brand_action)
    408 {
    409 	vnode_t		*nvp;
    410 	Ehdr		ehdr;
    411 	Addr		uphdr_vaddr;
    412 	intptr_t	voffset;
    413 	int		interp;
    414 	int		i, err;
    415 	struct execenv	env;
    416 	struct user	*up = PTOU(curproc);
    417 	sn1_proc_data_t	*spd;
    418 	sn1_elf_data_t	sed, *sedp;
    419 	char		*linker;
    420 	uintptr_t	lddata; /* lddata of executable's linker */
    421 
    422 	ASSERT(curproc->p_brand == &sn1_brand);
    423 	ASSERT(curproc->p_brand_data != NULL);
    424 
    425 	spd = (sn1_proc_data_t *)curproc->p_brand_data;
    426 	sedp = &spd->spd_elf_data;
    427 
    428 	args->brandname = SN1_BRANDNAME;
    429 
    430 	/*
    431 	 * We will exec the brand library and then map in the target
    432 	 * application and (optionally) the brand's default linker.
    433 	 */
    434 	if (args->to_model == DATAMODEL_NATIVE) {
    435 		args->emulator = SN1_LIB;
    436 		linker = SN1_LINKER;
    437 #if defined(_LP64)
    438 	} else {
    439 		args->emulator = SN1_LIB32;
    440 		linker = SN1_LINKER32;
    441 #endif /* _LP64 */
    442 	}
    443 
    444 	if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP,
    445 	    &nvp)) != 0) {
    446 		uprintf("%s: not found.", args->emulator);
    447 		return (err);
    448 	}
    449 
    450 	if (args->to_model == DATAMODEL_NATIVE) {
    451 		err = elfexec(nvp, uap, args, idatap, level + 1, execsz,
    452 		    setid, exec_file, cred, brand_action);
    453 #if defined(_LP64)
    454 	} else {
    455 		err = elf32exec(nvp, uap, args, idatap, level + 1, execsz,
    456 		    setid, exec_file, cred, brand_action);
    457 #endif /* _LP64 */
    458 	}
    459 	VN_RELE(nvp);
    460 	if (err != 0)
    461 		return (err);
    462 
    463 	/*
    464 	 * The u_auxv vectors are set up by elfexec to point to the brand
    465 	 * emulation library and linker.  Save these so they can be copied to
    466 	 * the specific brand aux vectors.
    467 	 */
    468 	bzero(&sed, sizeof (sed));
    469 	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
    470 		switch (up->u_auxv[i].a_type) {
    471 		case AT_SUN_LDDATA:
    472 			sed.sed_lddata = up->u_auxv[i].a_un.a_val;
    473 			break;
    474 		case AT_BASE:
    475 			sed.sed_base = up->u_auxv[i].a_un.a_val;
    476 			break;
    477 		case AT_ENTRY:
    478 			sed.sed_entry = up->u_auxv[i].a_un.a_val;
    479 			break;
    480 		case AT_PHDR:
    481 			sed.sed_phdr = up->u_auxv[i].a_un.a_val;
    482 			break;
    483 		case AT_PHENT:
    484 			sed.sed_phent = up->u_auxv[i].a_un.a_val;
    485 			break;
    486 		case AT_PHNUM:
    487 			sed.sed_phnum = up->u_auxv[i].a_un.a_val;
    488 			break;
    489 		default:
    490 			break;
    491 		}
    492 	}
    493 	/* Make sure the emulator has an entry point */
    494 	ASSERT(sed.sed_entry != NULL);
    495 	ASSERT(sed.sed_phdr != NULL);
    496 
    497 	bzero(&env, sizeof (env));
    498 	if (args->to_model == DATAMODEL_NATIVE) {
    499 		err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset,
    500 		    exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase,
    501 		    &env.ex_brksize, NULL);
    502 #if defined(_LP64)
    503 	} else {
    504 		Elf32_Ehdr ehdr32;
    505 		Elf32_Addr uphdr_vaddr32;
    506 		err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
    507 		    &voffset, exec_file, &interp, &env.ex_bssbase,
    508 		    &env.ex_brkbase, &env.ex_brksize, NULL);
    509 		Ehdr32to64(&ehdr32, &ehdr);
    510 		if (uphdr_vaddr32 == (Elf32_Addr)-1)
    511 			uphdr_vaddr = (Addr)-1;
    512 		else
    513 			uphdr_vaddr = uphdr_vaddr32;
    514 #endif /* _LP64 */
    515 	}
    516 	if (err != 0)
    517 		return (err);
    518 
    519 	/*
    520 	 * Save off the important properties of the executable. The brand
    521 	 * library will ask us for this data later, when it is initializing
    522 	 * and getting ready to transfer control to the brand application.
    523 	 */
    524 	if (uphdr_vaddr == (Addr)-1)
    525 		sedp->sed_phdr = voffset + ehdr.e_phoff;
    526 	else
    527 		sedp->sed_phdr = voffset + uphdr_vaddr;
    528 	sedp->sed_entry = voffset + ehdr.e_entry;
    529 	sedp->sed_phent = ehdr.e_phentsize;
    530 	sedp->sed_phnum = ehdr.e_phnum;
    531 
    532 	if (interp) {
    533 		if (ehdr.e_type == ET_DYN) {
    534 			/*
    535 			 * This is a shared object executable, so we need to
    536 			 * pick a reasonable place to put the heap. Just don't
    537 			 * use the first page.
    538 			 */
    539 			env.ex_brkbase = (caddr_t)PAGESIZE;
    540 			env.ex_bssbase = (caddr_t)PAGESIZE;
    541 		}
    542 
    543 		/*
    544 		 * If the program needs an interpreter (most do), map it in and
    545 		 * store relevant information about it in the aux vector, where
    546 		 * the brand library can find it.
    547 		 */
    548 		if ((err = lookupname(linker, UIO_SYSSPACE,
    549 		    FOLLOW, NULLVPP, &nvp)) != 0) {
    550 			uprintf("%s: not found.", SN1_LINKER);
    551 			return (err);
    552 		}
    553 		if (args->to_model == DATAMODEL_NATIVE) {
    554 			err = mapexec_brand(nvp, args, &ehdr,
    555 			    &uphdr_vaddr, &voffset, exec_file, &interp,
    556 			    NULL, NULL, NULL, &lddata);
    557 #if defined(_LP64)
    558 		} else {
    559 			Elf32_Ehdr ehdr32;
    560 			Elf32_Addr uphdr_vaddr32;
    561 			err = mapexec32_brand(nvp, args, &ehdr32,
    562 			    &uphdr_vaddr32, &voffset, exec_file, &interp,
    563 			    NULL, NULL, NULL, &lddata);
    564 			Ehdr32to64(&ehdr32, &ehdr);
    565 			if (uphdr_vaddr32 == (Elf32_Addr)-1)
    566 				uphdr_vaddr = (Addr)-1;
    567 			else
    568 				uphdr_vaddr = uphdr_vaddr32;
    569 #endif /* _LP64 */
    570 		}
    571 		VN_RELE(nvp);
    572 		if (err != 0)
    573 			return (err);
    574 
    575 		/*
    576 		 * Now that we know the base address of the brand's linker,
    577 		 * place it in the aux vector.
    578 		 */
    579 		sedp->sed_base = voffset;
    580 		sedp->sed_ldentry = voffset + ehdr.e_entry;
    581 		sedp->sed_lddata = voffset + lddata;
    582 	} else {
    583 		/*
    584 		 * This program has no interpreter. The brand library will
    585 		 * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector,
    586 		 * so in this case, put the entry point of the main executable
    587 		 * there.
    588 		 */
    589 		if (ehdr.e_type == ET_EXEC) {
    590 			/*
    591 			 * An executable with no interpreter, this must be a
    592 			 * statically linked executable, which means we loaded
    593 			 * it at the address specified in the elf header, in
    594 			 * which case the e_entry field of the elf header is an
    595 			 * absolute address.
    596 			 */
    597 			sedp->sed_ldentry = ehdr.e_entry;
    598 			sedp->sed_entry = ehdr.e_entry;
    599 			sedp->sed_lddata = NULL;
    600 			sedp->sed_base = NULL;
    601 		} else {
    602 			/*
    603 			 * A shared object with no interpreter, we use the
    604 			 * calculated address from above.
    605 			 */
    606 			sedp->sed_ldentry = sedp->sed_entry;
    607 			sedp->sed_entry = NULL;
    608 			sedp->sed_phdr = NULL;
    609 			sedp->sed_phent = NULL;
    610 			sedp->sed_phnum = NULL;
    611 			sedp->sed_lddata = NULL;
    612 			sedp->sed_base = voffset;
    613 
    614 			if (ehdr.e_type == ET_DYN) {
    615 				/*
    616 				 * Delay setting the brkbase until the first
    617 				 * call to brk(); see elfexec() for details.
    618 				 */
    619 				env.ex_bssbase = (caddr_t)0;
    620 				env.ex_brkbase = (caddr_t)0;
    621 				env.ex_brksize = 0;
    622 			}
    623 		}
    624 	}
    625 
    626 	env.ex_magic = elfmagic;
    627 	env.ex_vp = vp;
    628 	setexecenv(&env);
    629 
    630 	/*
    631 	 * It's time to manipulate the process aux vectors.  First
    632 	 * we need to update the AT_SUN_AUXFLAGS aux vector to set
    633 	 * the AF_SUN_NOPLM flag.
    634 	 */
    635 	if (args->to_model == DATAMODEL_NATIVE) {
    636 		auxv_t		auxflags_auxv;
    637 
    638 		if (copyin(args->auxp_auxflags, &auxflags_auxv,
    639 		    sizeof (auxflags_auxv)) != 0)
    640 			return (EFAULT);
    641 
    642 		ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
    643 		auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
    644 		if (copyout(&auxflags_auxv, args->auxp_auxflags,
    645 		    sizeof (auxflags_auxv)) != 0)
    646 			return (EFAULT);
    647 #if defined(_LP64)
    648 	} else {
    649 		auxv32_t	auxflags_auxv32;
    650 
    651 		if (copyin(args->auxp_auxflags, &auxflags_auxv32,
    652 		    sizeof (auxflags_auxv32)) != 0)
    653 			return (EFAULT);
    654 
    655 		ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
    656 		auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
    657 		if (copyout(&auxflags_auxv32, args->auxp_auxflags,
    658 		    sizeof (auxflags_auxv32)) != 0)
    659 			return (EFAULT);
    660 #endif /* _LP64 */
    661 	}
    662 
    663 	/* Second, copy out the brand specific aux vectors. */
    664 	if (args->to_model == DATAMODEL_NATIVE) {
    665 		auxv_t sn1_auxv[] = {
    666 		    { AT_SUN_BRAND_AUX1, 0 },
    667 		    { AT_SUN_BRAND_AUX2, 0 },
    668 		    { AT_SUN_BRAND_AUX3, 0 }
    669 		};
    670 
    671 		ASSERT(sn1_auxv[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
    672 		sn1_auxv[0].a_un.a_val = sed.sed_lddata;
    673 
    674 		if (copyout(&sn1_auxv, args->auxp_brand,
    675 		    sizeof (sn1_auxv)) != 0)
    676 			return (EFAULT);
    677 #if defined(_LP64)
    678 	} else {
    679 		auxv32_t sn1_auxv32[] = {
    680 		    { AT_SUN_BRAND_AUX1, 0 },
    681 		    { AT_SUN_BRAND_AUX2, 0 },
    682 		    { AT_SUN_BRAND_AUX3, 0 }
    683 		};
    684 
    685 		ASSERT(sn1_auxv32[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
    686 		sn1_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
    687 		if (copyout(&sn1_auxv32, args->auxp_brand,
    688 		    sizeof (sn1_auxv32)) != 0)
    689 			return (EFAULT);
    690 #endif /* _LP64 */
    691 	}
    692 
    693 	/*
    694 	 * Third, the the /proc aux vectors set up by elfexec() point to brand
    695 	 * emulation library and it's linker.  Copy these to the /proc brand
    696 	 * specific aux vector, and update the regular /proc aux vectors to
    697 	 * point to the executable (and it's linker).  This will enable
    698 	 * debuggers to access the executable via the usual /proc or elf notes
    699 	 * aux vectors.
    700 	 *
    701 	 * The brand emulation library's linker will get it's aux vectors off
    702 	 * the stack, and then update the stack with the executable's aux
    703 	 * vectors before jumping to the executable's linker.
    704 	 *
    705 	 * Debugging the brand emulation library must be done from
    706 	 * the global zone, where the librtld_db module knows how to fetch the
    707 	 * brand specific aux vectors to access the brand emulation libraries
    708 	 * linker.
    709 	 */
    710 	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
    711 		ulong_t val;
    712 
    713 		switch (up->u_auxv[i].a_type) {
    714 		case AT_SUN_BRAND_SN1_LDDATA:
    715 			up->u_auxv[i].a_un.a_val = sed.sed_lddata;
    716 			continue;
    717 		case AT_BASE:
    718 			val = sedp->sed_base;
    719 			break;
    720 		case AT_ENTRY:
    721 			val = sedp->sed_entry;
    722 			break;
    723 		case AT_PHDR:
    724 			val = sedp->sed_phdr;
    725 			break;
    726 		case AT_PHENT:
    727 			val = sedp->sed_phent;
    728 			break;
    729 		case AT_PHNUM:
    730 			val = sedp->sed_phnum;
    731 			break;
    732 		case AT_SUN_LDDATA:
    733 			val = sedp->sed_lddata;
    734 			break;
    735 		default:
    736 			continue;
    737 		}
    738 
    739 		up->u_auxv[i].a_un.a_val = val;
    740 		if (val == NULL) {
    741 			/* Hide the entry for static binaries */
    742 			up->u_auxv[i].a_type = AT_IGNORE;
    743 		}
    744 	}
    745 
    746 	/*
    747 	 * The last thing we do here is clear spd->spd_handler.  This is
    748 	 * important because if we're already a branded process and if this
    749 	 * exec succeeds, there is a window between when the exec() first
    750 	 * returns to the userland of the new process and when our brand
    751 	 * library get's initialized, during which we don't want system
    752 	 * calls to be re-directed to our brand library since it hasn't
    753 	 * been initialized yet.
    754 	 */
    755 	spd->spd_handler = NULL;
    756 
    757 	return (0);
    758 }
    759 
    760 
    761 int
    762 _init(void)
    763 {
    764 	int err;
    765 
    766 	/*
    767 	 * Set up the table indicating which system calls we want to
    768 	 * interpose on.  We should probably build this automatically from
    769 	 * a list of system calls that is shared with the user-space
    770 	 * library.
    771 	 */
    772 	sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
    773 	sn1_emulation_table[SYS_read] = 1;			/*   3 */
    774 	sn1_emulation_table[SYS_write] = 1;			/*   4 */
    775 	sn1_emulation_table[SYS_wait] = 1;			/*   7 */
    776 	sn1_emulation_table[SYS_time] = 1;			/*  13 */
    777 	sn1_emulation_table[SYS_getpid] = 1;			/*  20 */
    778 	sn1_emulation_table[SYS_mount] = 1;			/*  21 */
    779 	sn1_emulation_table[SYS_getuid] = 1;			/*  24 */
    780 	sn1_emulation_table[SYS_times] = 1;			/*  43 */
    781 	sn1_emulation_table[SYS_getgid] = 1;			/*  47 */
    782 	sn1_emulation_table[SYS_utssys] = 1;			/*  57 */
    783 	sn1_emulation_table[SYS_readlink] = 1;			/*  90 */
    784 	sn1_emulation_table[SYS_uname] = 1;			/* 135 */
    785 
    786 	err = mod_install(&modlinkage);
    787 	if (err) {
    788 		cmn_err(CE_WARN, "Couldn't install brand module");
    789 		kmem_free(sn1_emulation_table, NSYSCALL);
    790 	}
    791 
    792 	return (err);
    793 }
    794 
    795 int
    796 _info(struct modinfo *modinfop)
    797 {
    798 	return (mod_info(&modlinkage, modinfop));
    799 }
    800 
    801 int
    802 _fini(void)
    803 {
    804 	int err;
    805 
    806 	/*
    807 	 * If there are any zones using this brand, we can't allow it to be
    808 	 * unloaded.
    809 	 */
    810 	if (brand_zone_count(&sn1_brand))
    811 		return (EBUSY);
    812 
    813 	kmem_free(sn1_emulation_table, NSYSCALL);
    814 	sn1_emulation_table = NULL;
    815 
    816 	err = mod_remove(&modlinkage);
    817 	if (err)
    818 		cmn_err(CE_WARN, "Couldn't unload sn1 brand module");
    819 
    820 	return (err);
    821 }
    822