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