sn1_brand.c revision 628e3cbed6489fa1db545d8524a06cd6535af456
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * CDDL HEADER START
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * The contents of this file are subject to the terms of the
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Common Development and Distribution License (the "License").
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * You may not use this file except in compliance with the License.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * or http://www.opensolaris.org/os/licensing.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * See the License for the specific language governing permissions
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * and limitations under the License.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * When distributing Covered Code, include this CDDL HEADER in each
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * If applicable, add the following below this CDDL HEADER, with the
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * fields enclosed by brackets "[]" replaced with your own identifying
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * information: Portions Copyright [yyyy] [name of copyright owner]
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * CDDL HEADER END
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Use is subject to license terms.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/errno.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/exec.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/kmem.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/modctl.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/model.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/proc.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/syscall.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/systm.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/thread.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/cmn_err.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/archsystm.h>
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#include <sys/pathname.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/machbrand.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include <sys/brand.h>
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#include "sn1_brand.h"
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnchar *sn1_emulation_table = NULL;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
319378d99bca1eacf64f0a464b0175bf66b422abehvoid sn1_init_brand_data(zone_t *);
319378d99bca1eacf64f0a464b0175bf66b422abehvoid sn1_free_brand_data(zone_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_setbrand(proc_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint sn1_getattr(zone_t *, int, void *, size_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint sn1_setattr(zone_t *, int, void *, size_t);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn uintptr_t, uintptr_t, uintptr_t);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_copy_procdata(proc_t *, proc_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_proc_exit(struct proc *, klwp_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_exec();
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint sn1_initlwp(klwp_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_forklwp(klwp_t *, klwp_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_freelwp(klwp_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid sn1_lwpexit(klwp_t *);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn long *, int, caddr_t, cred_t *, int);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/* sn1 brand */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstruct brand_ops sn1_brops = {
319378d99bca1eacf64f0a464b0175bf66b422abeh sn1_init_brand_data,
319378d99bca1eacf64f0a464b0175bf66b422abeh sn1_free_brand_data,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brandsys,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_setbrand,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_getattr,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_setattr,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_copy_procdata,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_proc_exit,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_exec,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn lwp_setrval,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_initlwp,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_forklwp,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_freelwp,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_lwpexit,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_elfexec
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#ifdef sparc
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstruct brand_mach_ops sn1_mops = {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_syscall_callback,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_brand_syscall32_callback
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#else /* sparc */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#ifdef __amd64
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstruct brand_mach_ops sn1_mops = {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_sysenter_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_int91_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_syscall_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_syscall32_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#else /* ! __amd64 */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstruct brand_mach_ops sn1_mops = {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_sysenter_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_brand_syscall_callback,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn NULL
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#endif /* __amd64 */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn#endif /* _sparc */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstruct brand sn1_brand = {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn BRAND_VER_1,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn "sn1",
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn &sn1_brops,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn &sn1_mops
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstatic struct modlbrand modlbrand = {
c6f42f0e2681fa79ade12e054c64f3fc74e9e401edp &mod_brandops, /* type of module */
c6f42f0e2681fa79ade12e054c64f3fc74e9e401edp "Solaris N-1 Brand", /* description of module */
c6f42f0e2681fa79ade12e054c64f3fc74e9e401edp &sn1_brand /* driver ops */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnstatic struct modlinkage modlinkage = {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn MODREV_1, (void *)&modlbrand, NULL
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn};
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_setbrand(proc_t *p)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_brand == &sn1_brand);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_brand_data == NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp /*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * We should only be called from exec(), when we know the process
fd9e7635fa85e33de5aff912b955d797589f6f87edp * is single-threaded.
fd9e7635fa85e33de5aff912b955d797589f6f87edp */
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_tlist == p->p_tlist->t_forw);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz p->p_brand_data = kmem_zalloc(sizeof (sn1_proc_data_t), KM_SLEEP);
fd9e7635fa85e33de5aff912b955d797589f6f87edp (void) sn1_initlwp(p->p_tlist->t_lwp);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/* ARGSUSED */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (EINVAL);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/* ARGSUSED */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (EINVAL);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Get the address of the user-space system call handler from the user
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * process and attach it to the proc structure.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_proc_data_t *spd;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_brand_reg_t reg;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz proc_t *p = curproc;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz int err;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn *rval = 0;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
fd9e7635fa85e33de5aff912b955d797589f6f87edp /*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * There is one operation that is suppored for non-branded
fd9e7635fa85e33de5aff912b955d797589f6f87edp * process. B_EXEC_BRAND. This brand operaion is redundant
fd9e7635fa85e33de5aff912b955d797589f6f87edp * since the kernel assumes a native process doing an exec
fd9e7635fa85e33de5aff912b955d797589f6f87edp * in a branded zone is going to run a branded processes.
fd9e7635fa85e33de5aff912b955d797589f6f87edp * hence we don't support this operation.
fd9e7635fa85e33de5aff912b955d797589f6f87edp */
fd9e7635fa85e33de5aff912b955d797589f6f87edp if (cmd == B_EXEC_BRAND)
fd9e7635fa85e33de5aff912b955d797589f6f87edp return (ENOSYS);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp /* For all other operations this must be a branded process. */
fd9e7635fa85e33de5aff912b955d797589f6f87edp if (p->p_brand == &native_brand)
fd9e7635fa85e33de5aff912b955d797589f6f87edp return (ENOSYS);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(p->p_brand_data != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd = (sn1_proc_data_t *)p->p_brand_data;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz switch (cmd) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case B_EXEC_NATIVE:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = exec_common(
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz (char *)arg1, (const char **)arg2, (const char **)arg3,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz EBA_NATIVE);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case B_REGISTER:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (p->p_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyin((void *)arg1, &reg, sizeof (reg)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_brand_reg32_t reg32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyin((void *)arg1, &reg32, sizeof (reg32)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz reg.sbr_version = reg32.sbr_version;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (reg.sbr_version != SN1_VERSION)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (ENOTSUP);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd->spd_handler = reg.sbr_handler;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (0);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case B_ELFDATA:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (p->p_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&spd->spd_elf_data, (void *)arg1,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (sn1_elf_data_t)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_elf_data32_t sed32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_phent = spd->spd_elf_data.sed_phent;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_entry = spd->spd_elf_data.sed_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_base = spd->spd_elf_data.sed_base;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (0);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn }
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (EINVAL);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Copy the per-process brand data from a parent proc to a child.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_copy_procdata(proc_t *child, proc_t *parent)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_proc_data_t *spd;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(parent->p_brand == &sn1_brand);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(child->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(parent->p_brand_data != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(child->p_brand_data == NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Just duplicate all the proc data of the parent for the child */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd = kmem_alloc(sizeof (sn1_proc_data_t), KM_SLEEP);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz bcopy(parent->p_brand_data, spd, sizeof (sn1_proc_data_t));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz child->p_brand_data = spd;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_proc_exit(struct proc *p, klwp_t *l)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(p->p_brand_data != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp /*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * We should only be called from proc_exit(), when we know that
fd9e7635fa85e33de5aff912b955d797589f6f87edp * process is single-threaded.
fd9e7635fa85e33de5aff912b955d797589f6f87edp */
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_tlist == p->p_tlist->t_forw);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* upon exit, free our lwp brand data */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz (void) sn1_freelwp(ttolwp(curthread));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* upon exit, free our proc brand data */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz kmem_free(p->p_brand_data, sizeof (sn1_proc_data_t));
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn p->p_brand_data = NULL;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_exec()
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_proc_data_t *spd = curproc->p_brand_data;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(curproc->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(curproc->p_brand_data != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(ttolwp(curthread)->lwp_brand != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp /*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * We should only be called from exec(), when we know the process
fd9e7635fa85e33de5aff912b955d797589f6f87edp * is single-threaded.
fd9e7635fa85e33de5aff912b955d797589f6f87edp */
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Upon exec, reset our lwp brand data. */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz (void) sn1_freelwp(ttolwp(curthread));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz (void) sn1_initlwp(ttolwp(curthread));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Upon exec, reset all the proc brand data, except for the elf
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * data associated with the executable we are exec'ing.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd->spd_handler = NULL;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_initlwp(klwp_t *l)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_procp->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(l->lwp_procp->p_brand_data != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_brand == NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp l->lwp_brand = (void *)-1;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (0);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
319378d99bca1eacf64f0a464b0175bf66b422abeh/*ARGSUSED*/
319378d99bca1eacf64f0a464b0175bf66b422abehvoid
fd9e7635fa85e33de5aff912b955d797589f6f87edpsn1_forklwp(klwp_t *p, klwp_t *c)
319378d99bca1eacf64f0a464b0175bf66b422abeh{
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->lwp_procp->p_brand == &sn1_brand);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(c->lwp_procp->p_brand == &sn1_brand);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(p->lwp_procp->p_brand_data != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(c->lwp_procp->p_brand_data != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
fd9e7635fa85e33de5aff912b955d797589f6f87edp /* Both LWPs have already had been initialized via sn1_initlwp() */
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->lwp_brand != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(c->lwp_brand != NULL);
319378d99bca1eacf64f0a464b0175bf66b422abeh}
319378d99bca1eacf64f0a464b0175bf66b422abeh
319378d99bca1eacf64f0a464b0175bf66b422abeh/*ARGSUSED*/
319378d99bca1eacf64f0a464b0175bf66b422abehvoid
fd9e7635fa85e33de5aff912b955d797589f6f87edpsn1_freelwp(klwp_t *l)
319378d99bca1eacf64f0a464b0175bf66b422abeh{
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_procp->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(l->lwp_procp->p_brand_data != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_brand != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp l->lwp_brand = NULL;
319378d99bca1eacf64f0a464b0175bf66b422abeh}
319378d99bca1eacf64f0a464b0175bf66b422abeh
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
fd9e7635fa85e33de5aff912b955d797589f6f87edpsn1_lwpexit(klwp_t *l)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
fd9e7635fa85e33de5aff912b955d797589f6f87edp proc_t *p = l->lwp_procp;
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_procp->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(l->lwp_procp->p_brand_data != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(l->lwp_brand != NULL);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp /*
fd9e7635fa85e33de5aff912b955d797589f6f87edp * We should never be called for the last thread in a process.
fd9e7635fa85e33de5aff912b955d797589f6f87edp * (That case is handled by sn1_proc_exit().) There for this lwp
fd9e7635fa85e33de5aff912b955d797589f6f87edp * must be exiting from a multi-threaded process.
fd9e7635fa85e33de5aff912b955d797589f6f87edp */
fd9e7635fa85e33de5aff912b955d797589f6f87edp ASSERT(p->p_tlist != p->p_tlist->t_forw);
fd9e7635fa85e33de5aff912b955d797589f6f87edp
fd9e7635fa85e33de5aff912b955d797589f6f87edp l->lwp_brand = NULL;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowiczsn1_free_brand_data(zone_t *zone)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn/*ARGSUSED*/
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnvoid
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowiczsn1_init_brand_data(zone_t *zone)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz}
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowiczstatic void
628e3cbed6489fa1db545d8524a06cd6535af456Edward PilatowiczEhdr32to64(Elf32_Ehdr *src, Ehdr *dst)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_type = src->e_type;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_machine = src->e_machine;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_version = src->e_version;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_entry = src->e_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_phoff = src->e_phoff;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_shoff = src->e_shoff;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_flags = src->e_flags;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_ehsize = src->e_ehsize;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_phentsize = src->e_phentsize;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_phnum = src->e_phnum;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_shentsize = src->e_shentsize;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_shnum = src->e_shnum;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz dst->e_shstrndx = src->e_shstrndx;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnsn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn int brand_action)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz vnode_t *nvp;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Ehdr ehdr;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Addr uphdr_vaddr;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz intptr_t voffset;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz int interp;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz int i, err;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz struct execenv env;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz struct user *up = PTOU(curproc);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_proc_data_t *spd;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_elf_data_t sed, *sedp;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz char *linker;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uintptr_t lddata; /* lddata of executable's linker */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(curproc->p_brand == &sn1_brand);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(curproc->p_brand_data != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd = (sn1_proc_data_t *)curproc->p_brand_data;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp = &spd->spd_elf_data;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz args->brandname = SN1_BRANDNAME;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * We will exec the brand library and then map in the target
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * application and (optionally) the brand's default linker.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz args->emulator = SN1_LIB;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz linker = SN1_LINKER;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz args->emulator = SN1_LIB32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz linker = SN1_LINKER32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &nvp)) != 0) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uprintf("%s: not found.", args->emulator);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = elfexec(nvp, uap, args, idatap, level + 1, execsz,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz setid, exec_file, cred, brand_action);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = elf32exec(nvp, uap, args, idatap, level + 1, execsz,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz setid, exec_file, cred, brand_action);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz VN_RELE(nvp);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (err != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * The u_auxv vectors are set up by elfexec to point to the brand
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * emulation library and linker. Save these so they can be copied to
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * the specific brand aux vectors.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz bzero(&sed, sizeof (sed));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz switch (up->u_auxv[i].a_type) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_SUN_LDDATA:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_lddata = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_BASE:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_base = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_ENTRY:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_entry = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHDR:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_phdr = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHENT:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_phent = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHNUM:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sed.sed_phnum = up->u_auxv[i].a_un.a_val;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz default:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Make sure the emulator has an entry point */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(sed.sed_entry != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(sed.sed_phdr != NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz bzero(&env, sizeof (env));
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &env.ex_brksize, NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Elf32_Ehdr ehdr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Elf32_Addr uphdr_vaddr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &voffset, exec_file, &interp, &env.ex_bssbase,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &env.ex_brkbase, &env.ex_brksize, NULL);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Ehdr32to64(&ehdr32, &ehdr);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (uphdr_vaddr32 == (Elf32_Addr)-1)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uphdr_vaddr = (Addr)-1;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz else
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uphdr_vaddr = uphdr_vaddr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (err != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Save off the important properties of the executable. The brand
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * library will ask us for this data later, when it is initializing
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * and getting ready to transfer control to the brand application.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (uphdr_vaddr == (Addr)-1)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_phdr = voffset + ehdr.e_phoff;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz else
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_phdr = voffset + uphdr_vaddr;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_entry = voffset + ehdr.e_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_phent = ehdr.e_phentsize;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_phnum = ehdr.e_phnum;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (interp) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (ehdr.e_type == ET_DYN) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * This is a shared object executable, so we need to
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * pick a reasonable place to put the heap. Just don't
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * use the first page.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_brkbase = (caddr_t)PAGESIZE;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_bssbase = (caddr_t)PAGESIZE;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * If the program needs an interpreter (most do), map it in and
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * store relevant information about it in the aux vector, where
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * the brand library can find it.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if ((err = lookupname(linker, UIO_SYSSPACE,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz FOLLOW, NULLVPP, &nvp)) != 0) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uprintf("%s: not found.", SN1_LINKER);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = mapexec_brand(nvp, args, &ehdr,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &uphdr_vaddr, &voffset, exec_file, &interp,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz NULL, NULL, NULL, &lddata);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Elf32_Ehdr ehdr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Elf32_Addr uphdr_vaddr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz err = mapexec32_brand(nvp, args, &ehdr32,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz &uphdr_vaddr32, &voffset, exec_file, &interp,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz NULL, NULL, NULL, &lddata);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz Ehdr32to64(&ehdr32, &ehdr);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (uphdr_vaddr32 == (Elf32_Addr)-1)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uphdr_vaddr = (Addr)-1;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz else
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz uphdr_vaddr = uphdr_vaddr32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz VN_RELE(nvp);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (err != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (err);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Now that we know the base address of the brand's linker,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * place it in the aux vector.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_base = voffset;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_ldentry = voffset + ehdr.e_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_lddata = voffset + lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * This program has no interpreter. The brand library will
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * so in this case, put the entry point of the main executable
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * there.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (ehdr.e_type == ET_EXEC) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * An executable with no interpreter, this must be a
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * statically linked executable, which means we loaded
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * it at the address specified in the elf header, in
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * which case the e_entry field of the elf header is an
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * absolute address.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_ldentry = ehdr.e_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_entry = ehdr.e_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_lddata = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_base = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * A shared object with no interpreter, we use the
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * calculated address from above.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_ldentry = sedp->sed_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_lddata = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sedp->sed_base = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (uphdr_vaddr != (Addr)-1) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (ehdr.e_type == ET_DYN) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Delay setting the brkbase until the first call to
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * brk(); see elfexec() for details.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_bssbase = (caddr_t)0;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_brkbase = (caddr_t)0;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_brksize = 0;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_magic = elfmagic;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz env.ex_vp = vp;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz setexecenv(&env);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * It's time to manipulate the process aux vectors. First
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * we need to update the AT_SUN_AUXFLAGS aux vector to set
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * the AF_SUN_NOPLM flag.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxv_t auxflags_auxv;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyin(args->auxp_auxflags, &auxflags_auxv,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (auxflags_auxv)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&auxflags_auxv, args->auxp_auxflags,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (auxflags_auxv)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxv32_t auxflags_auxv32;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyin(args->auxp_auxflags, &auxflags_auxv32,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (auxflags_auxv32)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&auxflags_auxv32, args->auxp_auxflags,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (auxflags_auxv32)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Second, copy out the brand specific aux vectors. */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (args->to_model == DATAMODEL_NATIVE) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxv_t sn1_auxv[] = {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX1, 0 },
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX2, 0 },
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX3, 0 }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz };
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(sn1_auxv[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_auxv[0].a_un.a_val = sed.sed_lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&sn1_auxv, args->auxp_brand,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (sn1_auxv)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#if defined(_LP64)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz auxv32_t sn1_auxv32[] = {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX1, 0 },
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX2, 0 },
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz { AT_SUN_BRAND_AUX3, 0 }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz };
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz ASSERT(sn1_auxv32[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (copyout(&sn1_auxv32, args->auxp_brand,
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sizeof (sn1_auxv32)) != 0)
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (EFAULT);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz#endif /* _LP64 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Third, the the /proc aux vectors set up by elfexec() point to brand
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * emulation library and it's linker. Copy these to the /proc brand
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * specific aux vector, and update the regular /proc aux vectors to
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * point to the executable (and it's linker). This will enable
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * debuggers to access the executable via the usual /proc or elf notes
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * aux vectors.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz *
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * The brand emulation library's linker will get it's aux vectors off
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * the stack, and then update the stack with the executable's aux
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * vectors before jumping to the executable's linker.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz *
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * Debugging the brand emulation library must be done from
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * the global zone, where the librtld_db module knows how to fetch the
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * brand specific aux vectors to access the brand emulation libraries
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * linker.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz switch (up->u_auxv[i].a_type) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_SUN_BRAND_SN1_LDDATA:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sed.sed_lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_BASE:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (sedp->sed_base == NULL) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Hide base for static binaries */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_type = AT_IGNORE;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_base;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_ENTRY:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_entry;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHDR:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_phdr;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHENT:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_phent;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_PHNUM:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_phnum;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz case AT_SUN_LDDATA:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz if (sedp->sed_lddata == NULL) {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /* Hide lddata for static binaries */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_type = AT_IGNORE;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz } else {
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz up->u_auxv[i].a_un.a_val = sedp->sed_lddata;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz default:
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz break;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz }
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz /*
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * The last thing we do here is clear spd->spd_handler. This is
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * important because if we're already a branded process and if this
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * exec succeeds, there is a window between when the exec() first
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * returns to the userland of the new process and when our brand
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * library get's initialized, during which we don't want system
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * calls to be re-directed to our brand library since it hasn't
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz * been initialized yet.
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz spd->spd_handler = NULL;
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz return (0);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn_init(void)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn int err;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn /*
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * Set up the table indicating which system calls we want to
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * interpose on. We should probably build this automatically from
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * a list of system calls that is shared with the user-space
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * library.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_read] = 1; /* 3 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_write] = 1; /* 4 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_wait] = 1; /* 7 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_time] = 1; /* 13 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_getpid] = 1; /* 20 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_mount] = 1; /* 21 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_getuid] = 1; /* 24 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_times] = 1; /* 43 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_getgid] = 1; /* 47 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_utssys] = 1; /* 57 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_readlink] = 1; /* 90 */
628e3cbed6489fa1db545d8524a06cd6535af456Edward Pilatowicz sn1_emulation_table[SYS_uname] = 1; /* 135 */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn err = mod_install(&modlinkage);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn if (err) {
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn cmn_err(CE_WARN, "Couldn't install brand module");
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn kmem_free(sn1_emulation_table, NSYSCALL);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn }
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (err);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn_info(struct modinfo *modinfop)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (mod_info(&modlinkage, modinfop));
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnnint
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn_fini(void)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn{
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn int err;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn /*
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * If there are any zones using this brand, we can't allow it to be
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn * unloaded.
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn */
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn if (brand_zone_count(&sn1_brand))
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (EBUSY);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn kmem_free(sn1_emulation_table, NSYSCALL);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn sn1_emulation_table = NULL;
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn err = mod_remove(&modlinkage);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn if (err)
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn cmn_err(CE_WARN, "Couldn't unload sn1 brand module");
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn return (err);
9acbbeaf2a1ffe5c14b244867d427714fab43c5cnn}