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 2010 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_time] = 1;			/*  13 */
776 	sn1_emulation_table[SYS_getpid] = 1;			/*  20 */
777 	sn1_emulation_table[SYS_mount] = 1;			/*  21 */
778 	sn1_emulation_table[SYS_getuid] = 1;			/*  24 */
779 	sn1_emulation_table[SYS_times] = 1;			/*  43 */
780 	sn1_emulation_table[SYS_getgid] = 1;			/*  47 */
781 	sn1_emulation_table[SYS_utssys] = 1;			/*  57 */
782 	sn1_emulation_table[SYS_readlink] = 1;			/*  90 */
783 	sn1_emulation_table[SYS_waitid] = 1;			/* 107 */
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