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.
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.
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]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/errno.h>
27 #include <sys/systm.h>
28 #include <sys/cmn_err.h>
29 #include <sys/brand.h>
30 #include <sys/machbrand.h>
31 #include <sys/modctl.h>
32 #include <sys/rwlock.h>
34 #include <sys/pathname.h>
36 #define SUPPORTED_BRAND_VERSION BRAND_VER_1
38 #if defined(__sparcv9)
39 /* sparcv9 uses system wide brand interposition hooks */
40 static void brand_plat_interposition_enable(void);
41 static void brand_plat_interposition_disable(void);
43 struct brand_mach_ops native_mach_ops
= {
46 #else /* !__sparcv9 */
47 struct brand_mach_ops native_mach_ops
= {
48 NULL
, NULL
, NULL
, NULL
50 #endif /* !__sparcv9 */
52 brand_t native_brand
= {
60 * Used to maintain a list of all the brands currently loaded into the
65 struct brand_list
*bl_next
;
69 static struct brand_list
*brand_list
= NULL
;
72 * This lock protects the integrity of the brand list.
74 static kmutex_t brand_list_lock
;
79 mutex_init(&brand_list_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
80 p0
.p_brand
= &native_brand
;
84 brand_register(brand_t
*brand
)
86 struct brand_list
*list
, *scan
;
91 if (brand
->b_version
!= SUPPORTED_BRAND_VERSION
) {
92 if (brand
->b_version
< SUPPORTED_BRAND_VERSION
) {
94 "brand '%s' was built to run on older versions "
99 "brand '%s' was built to run on a newer version "
107 if (brand
->b_name
== NULL
|| brand
->b_ops
== NULL
||
108 brand
->b_ops
->b_brandsys
== NULL
) {
109 cmn_err(CE_WARN
, "Malformed brand");
113 list
= kmem_alloc(sizeof (struct brand_list
), KM_SLEEP
);
115 /* Add the brand to the list of loaded brands. */
116 mutex_enter(&brand_list_lock
);
119 * Check to be sure we haven't already registered this brand.
121 for (scan
= brand_list
; scan
!= NULL
; scan
= scan
->bl_next
) {
122 if (strcmp(brand
->b_name
, scan
->bl_brand
->b_name
) == 0) {
124 "Invalid attempt to load a second instance of "
125 "brand %s", brand
->b_name
);
126 mutex_exit(&brand_list_lock
);
127 kmem_free(list
, sizeof (struct brand_list
));
132 #if defined(__sparcv9)
133 /* sparcv9 uses system wide brand interposition hooks */
134 if (brand_list
== NULL
)
135 brand_plat_interposition_enable();
136 #endif /* __sparcv9 */
138 list
->bl_brand
= brand
;
140 list
->bl_next
= brand_list
;
143 mutex_exit(&brand_list_lock
);
149 * The kernel module implementing this brand is being unloaded, so remove
150 * it from the list of active brands.
153 brand_unregister(brand_t
*brand
)
155 struct brand_list
*list
, *prev
;
158 if (brand
== NULL
|| brand
->b_name
== NULL
) {
159 cmn_err(CE_WARN
, "Malformed brand");
164 mutex_enter(&brand_list_lock
);
166 for (list
= brand_list
; list
!= NULL
; list
= list
->bl_next
) {
167 if (list
->bl_brand
== brand
)
173 cmn_err(CE_WARN
, "Brand %s wasn't registered", brand
->b_name
);
174 mutex_exit(&brand_list_lock
);
178 if (list
->bl_refcnt
> 0) {
179 cmn_err(CE_WARN
, "Unregistering brand %s which is still in use",
181 mutex_exit(&brand_list_lock
);
185 /* Remove brand from the list */
187 prev
->bl_next
= list
->bl_next
;
189 brand_list
= list
->bl_next
;
191 #if defined(__sparcv9)
192 /* sparcv9 uses system wide brand interposition hooks */
193 if (brand_list
== NULL
)
194 brand_plat_interposition_disable();
195 #endif /* __sparcv9 */
197 mutex_exit(&brand_list_lock
);
199 kmem_free(list
, sizeof (struct brand_list
));
205 * Record that a zone of this brand has been instantiated. If the kernel
206 * module implementing this brand's functionality is not present, this
207 * routine attempts to load the module as a side effect.
210 brand_register_zone(struct brand_attr
*attr
)
212 struct brand_list
*l
= NULL
;
213 ddi_modhandle_t hdl
= NULL
;
218 * We make at most two passes through this loop. The first time
219 * through, we're looking to see if this is a new user of an
220 * already loaded brand. If the brand hasn't been loaded, we
221 * call ddi_modopen() to force it to be loaded and then make a
222 * second pass through the list of brands. If we don't find the
223 * brand the second time through it means that the modname
224 * specified in the brand_attr structure doesn't provide the brand
225 * specified in the brandname field. This would suggest a bug in
226 * the brand's config.xml file. We close the module and return
227 * 'NULL' to the caller.
231 * Search list of loaded brands
233 mutex_enter(&brand_list_lock
);
234 for (l
= brand_list
; l
!= NULL
; l
= l
->bl_next
)
235 if (strcmp(attr
->ba_brandname
,
236 l
->bl_brand
->b_name
) == 0)
238 if ((l
!= NULL
) || (hdl
!= NULL
))
240 mutex_exit(&brand_list_lock
);
243 * We didn't find that the requested brand has been loaded
244 * yet, so we trigger the load of the appropriate kernel
245 * module and search the list again.
247 modname
= kmem_alloc(MAXPATHLEN
, KM_SLEEP
);
248 (void) strcpy(modname
, "brand/");
249 (void) strcat(modname
, attr
->ba_modname
);
250 hdl
= ddi_modopen(modname
, KRTLD_MODE_FIRST
, &err
);
251 kmem_free(modname
, MAXPATHLEN
);
258 * If we found the matching brand, bump its reference count.
263 mutex_exit(&brand_list_lock
);
266 (void) ddi_modclose(hdl
);
268 return ((l
!= NULL
) ? l
->bl_brand
: NULL
);
272 * Return the number of zones currently using this brand.
275 brand_zone_count(struct brand
*bp
)
277 struct brand_list
*l
;
280 mutex_enter(&brand_list_lock
);
281 for (l
= brand_list
; l
!= NULL
; l
= l
->bl_next
)
282 if (l
->bl_brand
== bp
) {
286 mutex_exit(&brand_list_lock
);
292 brand_unregister_zone(struct brand
*bp
)
294 struct brand_list
*list
;
296 mutex_enter(&brand_list_lock
);
297 for (list
= brand_list
; list
!= NULL
; list
= list
->bl_next
) {
298 if (list
->bl_brand
== bp
) {
299 ASSERT(list
->bl_refcnt
> 0);
304 mutex_exit(&brand_list_lock
);
308 brand_setbrand(proc_t
*p
)
310 brand_t
*bp
= p
->p_zone
->zone_brand
;
313 ASSERT(p
->p_brand
== &native_brand
);
316 * We should only be called from exec(), when we know the process
317 * is single-threaded.
319 ASSERT(p
->p_tlist
== p
->p_tlist
->t_forw
);
322 ASSERT(PROC_IS_BRANDED(p
));
323 BROP(p
)->b_setbrand(p
);
327 brand_clearbrand(proc_t
*p
, boolean_t no_lwps
)
329 brand_t
*bp
= p
->p_zone
->zone_brand
;
332 ASSERT(!no_lwps
|| (p
->p_tlist
== NULL
));
335 * If called from exec_common() or proc_exit(),
336 * we know the process is single-threaded.
337 * If called from fork_fail, p_tlist is NULL.
340 ASSERT(p
->p_tlist
== p
->p_tlist
->t_forw
);
341 lwp
= p
->p_tlist
->t_lwp
;
344 ASSERT(PROC_IS_BRANDED(p
));
345 BROP(p
)->b_proc_exit(p
, lwp
);
346 p
->p_brand
= &native_brand
;
349 #if defined(__sparcv9)
351 * Currently, only sparc has system level brand syscall interposition.
352 * On x86 we're able to enable syscall interposition on a per-cpu basis
353 * when a branded thread is scheduled to run on a cpu.
356 /* Local variables needed for dynamic syscall interposition support */
357 static uint32_t syscall_trap_patch_instr_orig
;
358 static uint32_t syscall_trap32_patch_instr_orig
;
360 /* Trap Table syscall entry hot patch points */
361 extern void syscall_trap_patch_point(void);
362 extern void syscall_trap32_patch_point(void);
364 /* Alternate syscall entry handlers used when branded zones are running */
365 extern void syscall_wrapper(void);
366 extern void syscall_wrapper32(void);
368 /* Macros used to facilitate sparcv9 instruction generation */
369 #define BA_A_INSTR 0x30800000 /* ba,a addr */
370 #define DISP22(from, to) \
371 ((((uintptr_t)(to) - (uintptr_t)(from)) >> 2) & 0x3fffff)
375 brand_plat_interposition_enable(void)
377 ASSERT(MUTEX_HELD(&brand_list_lock
));
380 * Before we hot patch the kernel save the current instructions
381 * so that we can restore them later.
383 syscall_trap_patch_instr_orig
=
384 *(uint32_t *)syscall_trap_patch_point
;
385 syscall_trap32_patch_instr_orig
=
386 *(uint32_t *)syscall_trap32_patch_point
;
389 * Modify the trap table at the patch points.
391 * We basically replace the first instruction at the patch
392 * point with a ba,a instruction that will transfer control
393 * to syscall_wrapper or syscall_wrapper32 for 64-bit and
394 * 32-bit syscalls respectively. It's important to note that
395 * the annul bit is set in the branch so we don't execute
396 * the instruction directly following the one we're patching
397 * during the branch's delay slot.
399 * It also doesn't matter that we're not atomically updating both
400 * the 64 and 32 bit syscall paths at the same time since there's
401 * no actual branded processes running on the system yet.
403 hot_patch_kernel_text((caddr_t
)syscall_trap_patch_point
,
404 BA_A_INSTR
| DISP22(syscall_trap_patch_point
, syscall_wrapper
),
406 hot_patch_kernel_text((caddr_t
)syscall_trap32_patch_point
,
407 BA_A_INSTR
| DISP22(syscall_trap32_patch_point
, syscall_wrapper32
),
413 brand_plat_interposition_disable(void)
415 ASSERT(MUTEX_HELD(&brand_list_lock
));
418 * Restore the original instructions at the trap table syscall
419 * patch points to disable the brand syscall interposition
422 hot_patch_kernel_text((caddr_t
)syscall_trap_patch_point
,
423 syscall_trap_patch_instr_orig
, 4);
424 hot_patch_kernel_text((caddr_t
)syscall_trap32_patch_point
,
425 syscall_trap32_patch_instr_orig
, 4);
427 #endif /* __sparcv9 */
430 * The following functions can be shared among kernel brand modules which
431 * implement Solaris-derived brands, all of which need to do similar tasks
432 * to manage the brand.
437 Ehdr32to64(Elf32_Ehdr
*src
, Ehdr
*dst
)
439 bcopy(src
->e_ident
, dst
->e_ident
, sizeof (src
->e_ident
));
440 dst
->e_type
= src
->e_type
;
441 dst
->e_machine
= src
->e_machine
;
442 dst
->e_version
= src
->e_version
;
443 dst
->e_entry
= src
->e_entry
;
444 dst
->e_phoff
= src
->e_phoff
;
445 dst
->e_shoff
= src
->e_shoff
;
446 dst
->e_flags
= src
->e_flags
;
447 dst
->e_ehsize
= src
->e_ehsize
;
448 dst
->e_phentsize
= src
->e_phentsize
;
449 dst
->e_phnum
= src
->e_phnum
;
450 dst
->e_shentsize
= src
->e_shentsize
;
451 dst
->e_shnum
= src
->e_shnum
;
452 dst
->e_shstrndx
= src
->e_shstrndx
;
457 * Return -1 if the cmd was not handled by this function.
461 brand_solaris_cmd(int cmd
, uintptr_t arg1
, uintptr_t arg2
, uintptr_t arg3
,
462 struct brand
*pbrand
, int brandvers
)
464 brand_proc_data_t
*spd
;
465 brand_proc_reg_t reg
;
470 * There is one operation that is supported for a native
471 * process; B_EXEC_BRAND. This brand operaion is redundant
472 * since the kernel assumes a native process doing an exec
473 * in a branded zone is going to run a branded processes.
474 * hence we don't support this operation.
476 if (cmd
== B_EXEC_BRAND
)
479 /* For all other operations this must be a branded process. */
480 if (p
->p_brand
== &native_brand
)
483 ASSERT(p
->p_brand
== pbrand
);
484 ASSERT(p
->p_brand_data
!= NULL
);
486 spd
= (brand_proc_data_t
*)p
->p_brand_data
;
490 err
= exec_common((char *)arg1
, (const char **)arg2
,
491 (const char **)arg3
, EBA_NATIVE
);
495 * Get the address of the user-space system call handler from
496 * the user process and attach it to the proc structure.
499 if (p
->p_model
== DATAMODEL_NATIVE
) {
500 if (copyin((void *)arg1
, ®
, sizeof (reg
)) != 0)
505 brand_common_reg32_t reg32
;
507 if (copyin((void *)arg1
, ®32
, sizeof (reg32
)) != 0)
509 reg
.sbr_version
= reg32
.sbr_version
;
510 reg
.sbr_handler
= (caddr_t
)(uintptr_t)reg32
.sbr_handler
;
514 if (reg
.sbr_version
!= brandvers
)
516 spd
->spd_handler
= reg
.sbr_handler
;
520 if (p
->p_model
== DATAMODEL_NATIVE
) {
521 if (copyout(&spd
->spd_elf_data
, (void *)arg1
,
522 sizeof (brand_elf_data_t
)) != 0)
527 brand_elf_data32_t sed32
;
529 sed32
.sed_phdr
= spd
->spd_elf_data
.sed_phdr
;
530 sed32
.sed_phent
= spd
->spd_elf_data
.sed_phent
;
531 sed32
.sed_phnum
= spd
->spd_elf_data
.sed_phnum
;
532 sed32
.sed_entry
= spd
->spd_elf_data
.sed_entry
;
533 sed32
.sed_base
= spd
->spd_elf_data
.sed_base
;
534 sed32
.sed_ldentry
= spd
->spd_elf_data
.sed_ldentry
;
535 sed32
.sed_lddata
= spd
->spd_elf_data
.sed_lddata
;
536 if (copyout(&sed32
, (void *)arg1
, sizeof (sed32
))
544 * The B_TRUSS_POINT subcommand exists so that we can see
545 * truss output from interposed system calls that return
546 * without first calling any other system call, meaning they
547 * would be invisible to truss(1).
548 * If the second argument is set non-zero, set errno to that
551 * Common arguments seen with truss are:
553 * arg1: syscall number
557 return ((arg2
== 0) ? 0 : set_errno((uint_t
)arg2
));
565 brand_solaris_copy_procdata(proc_t
*child
, proc_t
*parent
, struct brand
*pbrand
)
567 brand_proc_data_t
*spd
;
569 ASSERT(parent
->p_brand
== pbrand
);
570 ASSERT(child
->p_brand
== pbrand
);
571 ASSERT(parent
->p_brand_data
!= NULL
);
572 ASSERT(child
->p_brand_data
== NULL
);
575 * Just duplicate all the proc data of the parent for the
578 spd
= kmem_alloc(sizeof (brand_proc_data_t
), KM_SLEEP
);
579 bcopy(parent
->p_brand_data
, spd
, sizeof (brand_proc_data_t
));
580 child
->p_brand_data
= spd
;
584 restoreexecenv(struct execenv
*ep
, stack_t
*sp
)
586 klwp_t
*lwp
= ttolwp(curthread
);
589 lwp
->lwp_sigaltstack
.ss_sp
= sp
->ss_sp
;
590 lwp
->lwp_sigaltstack
.ss_size
= sp
->ss_size
;
591 lwp
->lwp_sigaltstack
.ss_flags
= sp
->ss_flags
;
596 brand_solaris_elfexec(vnode_t
*vp
, execa_t
*uap
, uarg_t
*args
,
597 intpdata_t
*idatap
, int level
, long *execsz
, int setid
, caddr_t exec_file
,
598 cred_t
*cred
, int brand_action
, struct brand
*pbrand
, char *bname
,
599 char *brandlib
, char *brandlib32
, char *brandlinker
, char *brandlinker32
)
609 struct execenv origenv
;
610 stack_t orig_sigaltstack
;
611 struct user
*up
= PTOU(curproc
);
612 proc_t
*p
= ttoproc(curthread
);
613 klwp_t
*lwp
= ttolwp(curthread
);
614 brand_proc_data_t
*spd
;
615 brand_elf_data_t sed
, *sedp
;
617 uintptr_t lddata
; /* lddata of executable's linker */
619 ASSERT(curproc
->p_brand
== pbrand
);
620 ASSERT(curproc
->p_brand_data
!= NULL
);
622 spd
= (brand_proc_data_t
*)curproc
->p_brand_data
;
623 sedp
= &spd
->spd_elf_data
;
625 args
->brandname
= bname
;
628 * We will exec the brand library and then map in the target
629 * application and (optionally) the brand's default linker.
631 if (args
->to_model
== DATAMODEL_NATIVE
) {
632 args
->emulator
= brandlib
;
633 linker
= brandlinker
;
637 args
->emulator
= brandlib32
;
638 linker
= brandlinker32
;
642 if ((err
= lookupname(args
->emulator
, UIO_SYSSPACE
, FOLLOW
,
643 NULLVPP
, &nvp
)) != 0) {
644 uprintf("%s: not found.", args
->emulator
);
649 * The following elf{32}exec call changes the execenv in the proc
650 * struct which includes changing the p_exec member to be the vnode
651 * for the brand library (e.g. /.SUNWnative/usr/lib/s10_brand.so.1).
652 * We will eventually set the p_exec member to be the vnode for the new
653 * executable when we call setexecenv(). However, if we get an error
654 * before that call we need to restore the execenv to its original
655 * values so that when we return to the caller fop_close() works
656 * properly while cleaning up from the failed exec(). Restoring the
657 * original value will also properly decrement the 2nd VN_RELE that we
658 * took on the brand library.
660 origenv
.ex_bssbase
= p
->p_bssbase
;
661 origenv
.ex_brkbase
= p
->p_brkbase
;
662 origenv
.ex_brksize
= p
->p_brksize
;
663 origenv
.ex_vp
= p
->p_exec
;
664 orig_sigaltstack
.ss_sp
= lwp
->lwp_sigaltstack
.ss_sp
;
665 orig_sigaltstack
.ss_size
= lwp
->lwp_sigaltstack
.ss_size
;
666 orig_sigaltstack
.ss_flags
= lwp
->lwp_sigaltstack
.ss_flags
;
668 if (args
->to_model
== DATAMODEL_NATIVE
) {
669 err
= elfexec(nvp
, uap
, args
, idatap
, INTP_MAXDEPTH
+ 1, execsz
,
670 setid
, exec_file
, cred
, brand_action
);
674 err
= elf32exec(nvp
, uap
, args
, idatap
, INTP_MAXDEPTH
+ 1,
675 execsz
, setid
, exec_file
, cred
, brand_action
);
680 restoreexecenv(&origenv
, &orig_sigaltstack
);
685 * The u_auxv veCTors are set up by elfexec to point to the
686 * brand emulation library and linker. Save these so they can
687 * be copied to the specific brand aux vectors.
689 bzero(&sed
, sizeof (sed
));
690 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
691 switch (up
->u_auxv
[i
].a_type
) {
693 sed
.sed_lddata
= up
->u_auxv
[i
].a_un
.a_val
;
696 sed
.sed_base
= up
->u_auxv
[i
].a_un
.a_val
;
699 sed
.sed_entry
= up
->u_auxv
[i
].a_un
.a_val
;
702 sed
.sed_phdr
= up
->u_auxv
[i
].a_un
.a_val
;
705 sed
.sed_phent
= up
->u_auxv
[i
].a_un
.a_val
;
708 sed
.sed_phnum
= up
->u_auxv
[i
].a_un
.a_val
;
714 /* Make sure the emulator has an entry point */
715 ASSERT(sed
.sed_entry
!= NULL
);
716 ASSERT(sed
.sed_phdr
!= NULL
);
718 bzero(&env
, sizeof (env
));
719 if (args
->to_model
== DATAMODEL_NATIVE
) {
720 err
= mapexec_brand(vp
, args
, &ehdr
, &uphdr_vaddr
,
721 &voffset
, exec_file
, &interp
, &env
.ex_bssbase
,
722 &env
.ex_brkbase
, &env
.ex_brksize
, NULL
);
727 Elf32_Addr uphdr_vaddr32
;
728 err
= mapexec32_brand(vp
, args
, &ehdr32
, &uphdr_vaddr32
,
729 &voffset
, exec_file
, &interp
, &env
.ex_bssbase
,
730 &env
.ex_brkbase
, &env
.ex_brksize
, NULL
);
731 Ehdr32to64(&ehdr32
, &ehdr
);
733 if (uphdr_vaddr32
== (Elf32_Addr
)-1)
734 uphdr_vaddr
= (Addr
)-1;
736 uphdr_vaddr
= uphdr_vaddr32
;
740 restoreexecenv(&origenv
, &orig_sigaltstack
);
745 * Save off the important properties of the executable. The
746 * brand library will ask us for this data later, when it is
747 * initializing and getting ready to transfer control to the
750 if (uphdr_vaddr
== (Addr
)-1)
751 sedp
->sed_phdr
= voffset
+ ehdr
.e_phoff
;
753 sedp
->sed_phdr
= voffset
+ uphdr_vaddr
;
754 sedp
->sed_entry
= voffset
+ ehdr
.e_entry
;
755 sedp
->sed_phent
= ehdr
.e_phentsize
;
756 sedp
->sed_phnum
= ehdr
.e_phnum
;
759 if (ehdr
.e_type
== ET_DYN
) {
761 * This is a shared object executable, so we
762 * need to pick a reasonable place to put the
763 * heap. Just don't use the first page.
765 env
.ex_brkbase
= (caddr_t
)PAGESIZE
;
766 env
.ex_bssbase
= (caddr_t
)PAGESIZE
;
770 * If the program needs an interpreter (most do), map
771 * it in and store relevant information about it in the
772 * aux vector, where the brand library can find it.
774 if ((err
= lookupname(linker
, UIO_SYSSPACE
,
775 FOLLOW
, NULLVPP
, &nvp
)) != 0) {
776 uprintf("%s: not found.", brandlinker
);
777 restoreexecenv(&origenv
, &orig_sigaltstack
);
780 if (args
->to_model
== DATAMODEL_NATIVE
) {
781 err
= mapexec_brand(nvp
, args
, &ehdr
,
782 &uphdr_vaddr
, &voffset
, exec_file
, &interp
,
783 NULL
, NULL
, NULL
, &lddata
);
788 Elf32_Addr uphdr_vaddr32
;
789 err
= mapexec32_brand(nvp
, args
, &ehdr32
,
790 &uphdr_vaddr32
, &voffset
, exec_file
, &interp
,
791 NULL
, NULL
, NULL
, &lddata
);
792 Ehdr32to64(&ehdr32
, &ehdr
);
794 if (uphdr_vaddr32
== (Elf32_Addr
)-1)
795 uphdr_vaddr
= (Addr
)-1;
797 uphdr_vaddr
= uphdr_vaddr32
;
802 restoreexecenv(&origenv
, &orig_sigaltstack
);
807 * Now that we know the base address of the brand's
808 * linker, place it in the aux vector.
810 sedp
->sed_base
= voffset
;
811 sedp
->sed_ldentry
= voffset
+ ehdr
.e_entry
;
812 sedp
->sed_lddata
= voffset
+ lddata
;
815 * This program has no interpreter. The brand library
816 * will jump to the address in the AT_SUN_BRAND_LDENTRY
817 * aux vector, so in this case, put the entry point of
818 * the main executable there.
820 if (ehdr
.e_type
== ET_EXEC
) {
822 * An executable with no interpreter, this must
823 * be a statically linked executable, which
824 * means we loaded it at the address specified
825 * in the elf header, in which case the e_entry
826 * field of the elf header is an absolute
829 sedp
->sed_ldentry
= ehdr
.e_entry
;
830 sedp
->sed_entry
= ehdr
.e_entry
;
831 sedp
->sed_lddata
= NULL
;
832 sedp
->sed_base
= NULL
;
835 * A shared object with no interpreter, we use
836 * the calculated address from above.
838 sedp
->sed_ldentry
= sedp
->sed_entry
;
839 sedp
->sed_entry
= NULL
;
840 sedp
->sed_phdr
= NULL
;
841 sedp
->sed_phent
= NULL
;
842 sedp
->sed_phnum
= NULL
;
843 sedp
->sed_lddata
= NULL
;
844 sedp
->sed_base
= voffset
;
846 if (ehdr
.e_type
== ET_DYN
) {
848 * Delay setting the brkbase until the
849 * first call to brk(); see elfexec()
852 env
.ex_bssbase
= (caddr_t
)0;
853 env
.ex_brkbase
= (caddr_t
)0;
859 env
.ex_magic
= elfmagic
;
864 * It's time to manipulate the process aux vectors. First
865 * we need to update the AT_SUN_AUXFLAGS aux vector to set
866 * the AF_SUN_NOPLM flag.
868 if (args
->to_model
== DATAMODEL_NATIVE
) {
869 auxv_t auxflags_auxv
;
871 if (copyin(args
->auxp_auxflags
, &auxflags_auxv
,
872 sizeof (auxflags_auxv
)) != 0)
875 ASSERT(auxflags_auxv
.a_type
== AT_SUN_AUXFLAGS
);
876 auxflags_auxv
.a_un
.a_val
|= AF_SUN_NOPLM
;
877 if (copyout(&auxflags_auxv
, args
->auxp_auxflags
,
878 sizeof (auxflags_auxv
)) != 0)
883 auxv32_t auxflags_auxv32
;
885 if (copyin(args
->auxp_auxflags
, &auxflags_auxv32
,
886 sizeof (auxflags_auxv32
)) != 0)
889 ASSERT(auxflags_auxv32
.a_type
== AT_SUN_AUXFLAGS
);
890 auxflags_auxv32
.a_un
.a_val
|= AF_SUN_NOPLM
;
891 if (copyout(&auxflags_auxv32
, args
->auxp_auxflags
,
892 sizeof (auxflags_auxv32
)) != 0)
897 /* Second, copy out the brand specific aux vectors. */
898 if (args
->to_model
== DATAMODEL_NATIVE
) {
899 auxv_t brand_auxv
[] = {
900 { AT_SUN_BRAND_AUX1
, 0 },
901 { AT_SUN_BRAND_AUX2
, 0 },
902 { AT_SUN_BRAND_AUX3
, 0 }
905 ASSERT(brand_auxv
[0].a_type
==
906 AT_SUN_BRAND_COMMON_LDDATA
);
907 brand_auxv
[0].a_un
.a_val
= sed
.sed_lddata
;
909 if (copyout(&brand_auxv
, args
->auxp_brand
,
910 sizeof (brand_auxv
)) != 0)
915 auxv32_t brand_auxv32
[] = {
916 { AT_SUN_BRAND_AUX1
, 0 },
917 { AT_SUN_BRAND_AUX2
, 0 },
918 { AT_SUN_BRAND_AUX3
, 0 }
921 ASSERT(brand_auxv32
[0].a_type
== AT_SUN_BRAND_COMMON_LDDATA
);
922 brand_auxv32
[0].a_un
.a_val
= (uint32_t)sed
.sed_lddata
;
923 if (copyout(&brand_auxv32
, args
->auxp_brand
,
924 sizeof (brand_auxv32
)) != 0)
930 * Third, the /proc aux vectors set up by elfexec() point to
931 * brand emulation library and it's linker. Copy these to the
932 * /proc brand specific aux vector, and update the regular
933 * /proc aux vectors to point to the executable (and it's
934 * linker). This will enable debuggers to access the
935 * executable via the usual /proc or elf notes aux vectors.
937 * The brand emulation library's linker will get it's aux
938 * vectors off the stack, and then update the stack with the
939 * executable's aux vectors before jumping to the executable's
942 * Debugging the brand emulation library must be done from
943 * the global zone, where the librtld_db module knows how to
944 * fetch the brand specific aux vectors to access the brand
945 * emulation libraries linker.
947 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
950 switch (up
->u_auxv
[i
].a_type
) {
951 case AT_SUN_BRAND_COMMON_LDDATA
:
952 up
->u_auxv
[i
].a_un
.a_val
= sed
.sed_lddata
;
955 val
= sedp
->sed_base
;
958 val
= sedp
->sed_entry
;
961 val
= sedp
->sed_phdr
;
964 val
= sedp
->sed_phent
;
967 val
= sedp
->sed_phnum
;
970 val
= sedp
->sed_lddata
;
976 up
->u_auxv
[i
].a_un
.a_val
= val
;
978 /* Hide the entry for static binaries */
979 up
->u_auxv
[i
].a_type
= AT_IGNORE
;
984 * The last thing we do here is clear spd->spd_handler. This
985 * is important because if we're already a branded process and
986 * if this exec succeeds, there is a window between when the
987 * exec() first returns to the userland of the new process and
988 * when our brand library get's initialized, during which we
989 * don't want system calls to be re-directed to our brand
990 * library since it hasn't been initialized yet.
992 spd
->spd_handler
= NULL
;
998 brand_solaris_exec(struct brand
*pbrand
)
1000 brand_proc_data_t
*spd
= curproc
->p_brand_data
;
1002 ASSERT(curproc
->p_brand
== pbrand
);
1003 ASSERT(curproc
->p_brand_data
!= NULL
);
1004 ASSERT(ttolwp(curthread
)->lwp_brand
!= NULL
);
1007 * We should only be called from exec(), when we know the process
1008 * is single-threaded.
1010 ASSERT(curproc
->p_tlist
== curproc
->p_tlist
->t_forw
);
1012 /* Upon exec, reset our lwp brand data. */
1013 (void) brand_solaris_freelwp(ttolwp(curthread
), pbrand
);
1014 (void) brand_solaris_initlwp(ttolwp(curthread
), pbrand
);
1017 * Upon exec, reset all the proc brand data, except for the elf
1018 * data associated with the executable we are exec'ing.
1020 spd
->spd_handler
= NULL
;
1024 brand_solaris_fini(char **emul_table
, struct modlinkage
*modlinkage
,
1025 struct brand
*pbrand
)
1030 * If there are any zones using this brand, we can't allow it
1033 if (brand_zone_count(pbrand
))
1036 kmem_free(*emul_table
, NSYSCALL
);
1039 err
= mod_remove(modlinkage
);
1041 cmn_err(CE_WARN
, "Couldn't unload brand module");
1048 brand_solaris_forklwp(klwp_t
*p
, klwp_t
*c
, struct brand
*pbrand
)
1050 ASSERT(p
->lwp_procp
->p_brand
== pbrand
);
1051 ASSERT(c
->lwp_procp
->p_brand
== pbrand
);
1053 ASSERT(p
->lwp_procp
->p_brand_data
!= NULL
);
1054 ASSERT(c
->lwp_procp
->p_brand_data
!= NULL
);
1057 * Both LWPs have already had been initialized via
1058 * brand_solaris_initlwp().
1060 ASSERT(p
->lwp_brand
!= NULL
);
1061 ASSERT(c
->lwp_brand
!= NULL
);
1066 brand_solaris_freelwp(klwp_t
*l
, struct brand
*pbrand
)
1068 ASSERT(l
->lwp_procp
->p_brand
== pbrand
);
1069 ASSERT(l
->lwp_procp
->p_brand_data
!= NULL
);
1070 ASSERT(l
->lwp_brand
!= NULL
);
1071 l
->lwp_brand
= NULL
;
1076 brand_solaris_initlwp(klwp_t
*l
, struct brand
*pbrand
)
1078 ASSERT(l
->lwp_procp
->p_brand
== pbrand
);
1079 ASSERT(l
->lwp_procp
->p_brand_data
!= NULL
);
1080 ASSERT(l
->lwp_brand
== NULL
);
1081 l
->lwp_brand
= (void *)-1;
1087 brand_solaris_lwpexit(klwp_t
*l
, struct brand
*pbrand
)
1089 proc_t
*p
= l
->lwp_procp
;
1091 ASSERT(l
->lwp_procp
->p_brand
== pbrand
);
1092 ASSERT(l
->lwp_procp
->p_brand_data
!= NULL
);
1093 ASSERT(l
->lwp_brand
!= NULL
);
1096 * We should never be called for the last thread in a process.
1097 * (That case is handled by brand_solaris_proc_exit().)
1098 * Therefore this lwp must be exiting from a multi-threaded
1101 ASSERT(p
->p_tlist
!= p
->p_tlist
->t_forw
);
1103 l
->lwp_brand
= NULL
;
1108 brand_solaris_proc_exit(struct proc
*p
, klwp_t
*l
, struct brand
*pbrand
)
1110 ASSERT(p
->p_brand
== pbrand
);
1111 ASSERT(p
->p_brand_data
!= NULL
);
1114 * When called from proc_exit(), we know that process is
1115 * single-threaded and free our lwp brand data.
1116 * otherwise just free p_brand_data and return.
1119 ASSERT(p
->p_tlist
== p
->p_tlist
->t_forw
);
1120 ASSERT(p
->p_tlist
->t_lwp
== l
);
1121 (void) brand_solaris_freelwp(l
, pbrand
);
1124 /* upon exit, free our proc brand data */
1125 kmem_free(p
->p_brand_data
, sizeof (brand_proc_data_t
));
1126 p
->p_brand_data
= NULL
;
1130 brand_solaris_setbrand(proc_t
*p
, struct brand
*pbrand
)
1132 ASSERT(p
->p_brand
== pbrand
);
1133 ASSERT(p
->p_brand_data
== NULL
);
1136 * We should only be called from exec(), when we know the process
1137 * is single-threaded.
1139 ASSERT(p
->p_tlist
== p
->p_tlist
->t_forw
);
1141 p
->p_brand_data
= kmem_zalloc(sizeof (brand_proc_data_t
), KM_SLEEP
);
1142 (void) brand_solaris_initlwp(p
->p_tlist
->t_lwp
, pbrand
);