changeset 10840:7df556caf412

PSARC 2009/253 S10C 6666646 Solaris 10 zones on OpenSolaris binary (supported) distributions
author Gerald Jelinek <Gerald.Jelinek@Sun.COM>
date Thu, 22 Oct 2009 11:21:27 -0700
parents cf83b553a2ab
children d3e4a10fc7d5
files usr/src/Makefile.lint usr/src/Targetdirs usr/src/lib/brand/Makefile usr/src/lib/brand/Makefile.brand usr/src/lib/brand/lx/lx_support/Makefile usr/src/lib/brand/native/zone/Makefile usr/src/lib/brand/native/zone/common.ksh usr/src/lib/brand/native/zone/query.ksh usr/src/lib/brand/native/zone/uninstall.ksh usr/src/lib/brand/sn1/librtld_db/Makefile.com usr/src/lib/brand/sn1/sn1_brand/Makefile usr/src/lib/brand/sn1/zone/config.xml usr/src/lib/brand/sn1/zone/platform.xml usr/src/lib/brand/solaris10/Makefile usr/src/lib/brand/solaris10/Makefile.s10 usr/src/lib/brand/solaris10/cmd/Makefile usr/src/lib/brand/solaris10/cmd/s10_automount.sh usr/src/lib/brand/solaris10/cmd/s10_automountd.sh usr/src/lib/brand/solaris10/cmd/s10_isaexec_wrapper.sh usr/src/lib/brand/solaris10/cmd/s10_native.sh usr/src/lib/brand/solaris10/librtld_db/Makefile usr/src/lib/brand/solaris10/librtld_db/Makefile.com usr/src/lib/brand/solaris10/librtld_db/amd64/Makefile usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers.64 usr/src/lib/brand/solaris10/librtld_db/common/solaris10_librtld_db.c usr/src/lib/brand/solaris10/librtld_db/i386/Makefile usr/src/lib/brand/solaris10/librtld_db/sparc/Makefile usr/src/lib/brand/solaris10/librtld_db/sparcv9/Makefile usr/src/lib/brand/solaris10/s10_brand/Makefile usr/src/lib/brand/solaris10/s10_brand/Makefile.com usr/src/lib/brand/solaris10/s10_brand/amd64/Makefile usr/src/lib/brand/solaris10/s10_brand/amd64/s10_crt.s usr/src/lib/brand/solaris10/s10_brand/amd64/s10_handler.s usr/src/lib/brand/solaris10/s10_brand/amd64/s10_runexe.s usr/src/lib/brand/solaris10/s10_brand/common/mapfile-vers usr/src/lib/brand/solaris10/s10_brand/common/offsets.in usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c usr/src/lib/brand/solaris10/s10_brand/i386/Makefile usr/src/lib/brand/solaris10/s10_brand/i386/s10_crt.s usr/src/lib/brand/solaris10/s10_brand/i386/s10_handler.s usr/src/lib/brand/solaris10/s10_brand/i386/s10_runexe.s usr/src/lib/brand/solaris10/s10_brand/sparc/Makefile usr/src/lib/brand/solaris10/s10_brand/sparc/s10_crt.s usr/src/lib/brand/solaris10/s10_brand/sparc/s10_handler.s usr/src/lib/brand/solaris10/s10_brand/sparc/s10_runexe.s usr/src/lib/brand/solaris10/s10_brand/sparcv9/Makefile usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h usr/src/lib/brand/solaris10/s10_npreload/Makefile usr/src/lib/brand/solaris10/s10_npreload/Makefile.com usr/src/lib/brand/solaris10/s10_npreload/amd64/Makefile usr/src/lib/brand/solaris10/s10_npreload/common/mapfile-vers usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c usr/src/lib/brand/solaris10/s10_npreload/i386/Makefile usr/src/lib/brand/solaris10/s10_npreload/sparc/Makefile usr/src/lib/brand/solaris10/s10_npreload/sparcv9/Makefile usr/src/lib/brand/solaris10/s10_support/Makefile usr/src/lib/brand/solaris10/s10_support/s10_support.c usr/src/lib/brand/solaris10/zone/Makefile usr/src/lib/brand/solaris10/zone/SUNWsolaris10.xml usr/src/lib/brand/solaris10/zone/attach.ksh usr/src/lib/brand/solaris10/zone/clone.ksh usr/src/lib/brand/solaris10/zone/common.ksh usr/src/lib/brand/solaris10/zone/config.xml usr/src/lib/brand/solaris10/zone/detach.ksh usr/src/lib/brand/solaris10/zone/image_install.ksh usr/src/lib/brand/solaris10/zone/p2v.ksh usr/src/lib/brand/solaris10/zone/pkgrm.conf usr/src/lib/brand/solaris10/zone/pkgrm.lst usr/src/lib/brand/solaris10/zone/platform.xml usr/src/lib/brand/solaris10/zone/poststate.ksh usr/src/lib/brand/solaris10/zone/prestate.ksh usr/src/lib/brand/solaris10/zone/s10_boot.ksh usr/src/lib/brand/solaris10/zone/smf_disable.conf usr/src/lib/brand/solaris10/zone/smf_disable.lst usr/src/lib/brand/solaris10/zone/uninstall.ksh usr/src/lib/brand/solaris10/zone/version usr/src/pkgdefs/Makefile usr/src/pkgdefs/SUNWs10brandr/Makefile usr/src/pkgdefs/SUNWs10brandr/depend usr/src/pkgdefs/SUNWs10brandr/pkginfo.tmpl usr/src/pkgdefs/SUNWs10brandr/prototype_com usr/src/pkgdefs/SUNWs10brandr/prototype_i386 usr/src/pkgdefs/SUNWs10brandr/prototype_sparc usr/src/pkgdefs/SUNWs10brandu/Makefile usr/src/pkgdefs/SUNWs10brandu/depend usr/src/pkgdefs/SUNWs10brandu/pkginfo.tmpl usr/src/pkgdefs/SUNWs10brandu/prototype_com usr/src/pkgdefs/SUNWs10brandu/prototype_i386 usr/src/pkgdefs/SUNWs10brandu/prototype_sparc usr/src/pkgdefs/SUNWzoneu/prototype_com usr/src/uts/common/Makefile.rules usr/src/uts/common/brand/sn1/sn1_brand.c usr/src/uts/common/brand/solaris10/s10_brand.c usr/src/uts/common/brand/solaris10/s10_brand.h usr/src/uts/common/brand/solaris10/s10_offsets.in usr/src/uts/intel/Makefile.files usr/src/uts/intel/Makefile.intel.shared usr/src/uts/intel/Makefile.rules usr/src/uts/intel/brand/solaris10/s10_brand_asm.s usr/src/uts/intel/s10_brand/Makefile usr/src/uts/sun4/brand/solaris10/s10_brand_asm.s usr/src/uts/sun4u/Makefile.files usr/src/uts/sun4u/Makefile.rules usr/src/uts/sun4u/Makefile.sun4u.shared usr/src/uts/sun4u/s10_brand/Makefile usr/src/uts/sun4v/Makefile.files usr/src/uts/sun4v/Makefile.rules usr/src/uts/sun4v/Makefile.sun4v.shared usr/src/uts/sun4v/s10_brand/Makefile
diffstat 110 files changed, 11500 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/Makefile.lint	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/Makefile.lint	Thu Oct 22 11:21:27 2009 -0700
@@ -329,6 +329,7 @@
 	lib/auditd_plugins \
 	lib/brand/native \
 	lib/brand/sn1 \
+	lib/brand/solaris10 \
 	lib/cfgadm_plugins/sdcard \
 	lib/crypt_modules \
 	lib/extendedFILE \
--- a/usr/src/Targetdirs	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/Targetdirs	Thu Oct 22 11:21:27 2009 -0700
@@ -88,6 +88,7 @@
 	/etc \
 	/etc/brand  \
 	/etc/brand/native  \
+	/etc/brand/solaris10  \
 	/etc/certs	\
 	/etc/cron.d \
 	/etc/crypto \
@@ -209,6 +210,7 @@
 	/usr/lib/brand/native \
 	/usr/lib/brand/shared \
 	/usr/lib/brand/sn1 \
+	/usr/lib/brand/solaris10 \
 	/usr/lib/class \
 	/usr/lib/class/FSS \
 	/usr/lib/class/FX \
@@ -408,6 +410,7 @@
 	/usr/lib/$(MACH64) \
 	/usr/lib/$(MACH64)/gss \
 	/usr/lib/brand/sn1/$(MACH64) \
+	/usr/lib/brand/solaris10/$(MACH64) \
 	/usr/lib/elfedit/$(MACH64) \
 	/usr/lib/fm/$(MACH64) \
 	/usr/lib/fs/nfs/$(MACH64) \
@@ -481,6 +484,7 @@
 	/lib/secure/64 \
 	/usr/lib/64 \
 	/usr/lib/brand/sn1/64 \
+	/usr/lib/brand/solaris10/64 \
 	/usr/lib/elfedit/64 \
 	/usr/lib/libp/64 \
 	/usr/lib/link_audit/64 \
@@ -589,6 +593,7 @@
 $(BUILD64) $(ROOT)/usr/lib/elfedit/64:=	LINKDEST=$(MACH64)
 $(BUILD64) $(ROOT)/usr/lib/brand/lx/64:=	LINKDEST=$(MACH64)
 $(BUILD64) $(ROOT)/usr/lib/brand/sn1/64:=	LINKDEST=$(MACH64)
+$(BUILD64) $(ROOT)/usr/lib/brand/solaris10/64:=	LINKDEST=$(MACH64)
 $(BUILD64) $(ROOT)/usr/lib/libp/64:=	LINKDEST=$(MACH64)
 $(BUILD64) $(ROOT)/usr/lib/lwp/64:=	LINKDEST=$(MACH64)
 $(BUILD64) $(ROOT)/usr/lib/link_audit/64:=	LINKDEST=$(MACH64)
--- a/usr/src/lib/brand/Makefile	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -34,8 +34,8 @@
 i386_SUBDIRS= lx
 i386_MSGSUBDIRS= lx
 
-SUBDIRS= sn1 native $($(MACH)_SUBDIRS)
-MSGSUBDIRS= native $($(MACH)_MSGSUBDIRS)
+SUBDIRS= sn1 solaris10 native $($(MACH)_SUBDIRS)
+MSGSUBDIRS= solaris10 native $($(MACH)_MSGSUBDIRS)
 
 all :=		TARGET= all
 install :=	TARGET= install
--- a/usr/src/lib/brand/Makefile.brand	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/Makefile.brand	Thu Oct 22 11:21:27 2009 -0700
@@ -30,11 +30,13 @@
 ROOTBRANDDIR=	$(ROOTDIR)/$(BRAND)
 ROOTBRANDDIR64=	$(ROOTDIR)/$(BRAND)/$(MACH64)
 ROOTSHAREDDIR=	$(ROOTDIR)/shared
+ETCBRANDDIR=	$(ROOT)/etc/brand/$(BRAND)
 
 ROOTPROGS=	$(PROGS:%=$(ROOTBRANDDIR)/%)
 ROOTTXTS=	$(TXTS:%=$(ROOTBRANDDIR)/%)
 ROOTXMLDOCS=	$(XMLDOCS:%=$(ROOTBRANDDIR)/%)
 ROOTSHARED=	$(SHARED:%=$(ROOTSHAREDDIR)/%)
+ETCUSER=	$(USERFILES:%=$(ETCBRANDDIR)/%)
 
 ROOTTEMPLATES=	$(TEMPLATES:%=$(ROOTTEMPLATEDIR)/%)
 
@@ -42,7 +44,7 @@
 
 $(ROOTXMLDOCS) :=	FILEMODE = 444
 
-$(ROOTSHARED) :=	FILEMODE = 444
+$(ROOTSHARED) :=	FILEMODE = 755
 
 $(ROOTTEMPLATEDIR) :=	FILEMODE = 755
 
@@ -52,9 +54,13 @@
 
 $(ROOTPROGS) :=	FILEMODE = 755
 
-$(ROOTBRANDDIR)/% $(ROOTBRANDDIR64)/% $(ROOTTEMPLATEDIR)/% $(ROOTSHAREDDIR)/%: %
+$(ROOTBRANDDIR)/% $(ROOTBRANDDIR64)/% $(ROOTTEMPLATEDIR)/% $(ROOTSHAREDDIR)/% $(ETCBRANDDIR)/%: %
 	$(INS.file)
 
+$(ETCUSER) :=	FILEMODE = 644
+$(ETCUSER) :=	OWNER = root
+$(ETCUSER) :=	GROUP = sys
+
 .SUFFIXES:	.ksh
 
 .ksh:
--- a/usr/src/lib/brand/lx/lx_support/Makefile	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/lx/lx_support/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -19,10 +19,9 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
 
 PROG =		lx_support
 PROGS =		$(PROG)
@@ -31,13 +30,13 @@
 all:		$(PROG)
 
 include ../Makefile.lx
-include ../../../../cmd/Makefile.cmd
+include $(SRC)/cmd/Makefile.cmd
 
 # override the install directory
 ROOTBIN =	$(ROOTBRANDDIR)
 CLOBBERFILES =	$(OBJS) $(ROOTPROGS)
 
-UTSBASE =	../../../../uts
+UTSBASE =	$(SRC)/uts
 
 CFLAGS +=	$(CCVERBOSE)
 CPPFLAGS +=	-D_REENTRANT -I$(UTSBASE)/common/brand/lx
@@ -52,4 +51,4 @@
 
 lint:		lint_PROG
 
-include ../../../../cmd/Makefile.targ
+include $(SRC)/cmd/Makefile.targ
--- a/usr/src/lib/brand/native/zone/Makefile	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/native/zone/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -24,19 +24,12 @@
 # Use is subject to license terms.
 #
 
-ETCBRANDDIR=	$(ROOT)/etc/brand/native
-ETCUSER=	$(USERFILES:%=$(ETCBRANDDIR)/%)
-$(ETCUSER) :=	FILEMODE = 644
-
-$(ETCBRANDDIR)/%: %
-	$(INS.file)
-
 PROG=		sw_support
 BRAND=		native
 PROGS=		attach_update image_install p2v $(PROG)
 XMLDOCS=	config.xml platform.xml smf_disable.lst pkgrm.lst
 USERFILES=	smf_disable.conf pkgrm.conf
-SHARED=		common.ksh
+SHARED=		common.ksh query uninstall.ksh
 TEMPLATES=	SUNWdefault.xml SUNWblank.xml
 CLOBBERFILES=	$(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ROOTSHARED) \
 	$(ETCUSER)
@@ -46,10 +39,13 @@
 include $(SRC)/cmd/Makefile.cmd
 include ../../Makefile.brand
 
+$(ROOTSHAREDDIR)/common.ksh := FILEMODE = 444
+$(ROOTSHAREDDIR)/uninstall.ksh := FILEMODE = 444
+
 CPPFLAGS +=	-I/usr/include/libxml2 -D_REENTRANT
 LDLIBS += -lzonecfg -luutil
 
-POFILES=	$(PROGS:%=%.po) common.po
+POFILES=	$(PROGS:%=%.po) common.po query.po uninstall.po
 POFILE=		native_zone.po
 
 $(POFILE): $(POFILES)
--- a/usr/src/lib/brand/native/zone/common.ksh	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/native/zone/common.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -43,6 +43,13 @@
 	exit $EXIT_CODE
 }
 
+fail_fatal() {
+	printf "ERROR: "
+	printf "$@"
+	printf "\n"
+	exit $ZONE_SUBPROC_FATAL
+}
+
 #
 # Send the provided printf()-style arguments to the screen and to the logfile.
 #
@@ -68,7 +75,24 @@
         [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2
 }
 
+#
 # Validate that the directory is safe.
+#
+# It is possible for a malicious zone root user to modify a zone's filesystem
+# so that modifications made to the zone's filesystem by administrators in the
+# global zone modify the global zone's filesystem.  We can prevent this by
+# ensuring that all components of paths accessed by scripts are real (i.e.,
+# non-symlink) directories.
+#
+# NOTE: The specified path should be an absolute path as would be seen from
+# within the zone.  Also, this function does not check parent directories.
+# If, for example, you need to ensure that every component of the path
+# '/foo/bar/baz' is a directory and not a symlink, then do the following:
+#
+#	safe_dir /foo
+#	safe_dir /foo/bar
+#	safe_dir /foo/bar/baz
+#
 safe_dir()
 {
 	typeset dir="$1"
@@ -78,6 +102,18 @@
 	fi
 }
 
+# Like safe_dir except the dir doesn't have to exist.
+safe_opt_dir()
+{
+	typeset dir="$1"
+
+	[[ ! -e $ZONEROOT/$dir ]] && return
+
+	if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then
+		fatal "$e_baddir" "$dir"
+	fi
+}
+
 # Only make a copy if we haven't already done so.
 safe_backup()
 {
@@ -111,6 +147,64 @@
 	fi
 }
 
+safe_rm()
+{
+	if [[ ! -h $ZONEROOT/$1 && -f $ZONEROOT/$1 ]]; then
+		rm -f "$ZONEROOT/$1"
+	fi
+}
+
+#
+# Replace the file with a wrapper pointing to the native brand code.
+# However, we only do the replacement if the file hasn't already been
+# replaced with our wrapper.  This function expects the cwd to be the
+# location of the file we're replacing.
+#
+# Some of the files we're replacing are hardlinks to isaexec so we need to 'rm'
+# the file before we setup the wrapper while others are hardlinks to rc scripts
+# that we need to maintain.
+#
+safe_replace()
+{
+	typeset filename="$1"
+	typeset runname="$2"
+	typeset mode="$3"
+	typeset own="$4"
+	typeset rem="$5"
+
+	if [ -h $filename -o ! -f $filename ]; then
+		return
+	fi
+
+	egrep -s "Solaris Brand Replacement" $filename
+	if [ $? -eq 0 ]; then
+		return
+	fi
+
+	safe_backup $filename $filename.pre_p2v
+	if [ $rem = "remove" ]; then
+		rm -f $filename
+	fi
+
+	cat <<-END >$filename || exit 1
+	#!/bin/sh
+	#
+	# Solaris Brand Replacement
+	#
+	# Attention.  This file has been replaced with a new version for
+	# use in a virtualized environment.  Modification of this script is not
+	# supported and all changes will be lost upon reboot.  The
+	# {name}.pre_p2v version of this file is a backup copy of the
+	# original and should not be deleted.
+	#
+	END
+
+	echo ". $runname \"\$@\"" >>$filename || exit 1
+
+	chmod $mode $filename
+	chown $own $filename
+}
+
 #
 # Read zonecfg ipd and fs entries and save the relevant data, one entry per
 # line.
@@ -218,6 +312,19 @@
 	}' >>$LOGFILE
 }
 
+# Find the dataset mounted on the zonepath.
+get_zonepath_ds() {
+	ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \
+	    /usr/bin/nawk -v zonepath=$1 '{
+		if ($2 == zonepath)
+			print $1
+	}'`
+
+	if [ -z "$ZONEPATH_DS" ]; then
+		fail_fatal "$f_no_ds"
+	fi
+}
+
 #
 # Perform any cleanup in the zoneroot after unpacking the archive.
 #
@@ -893,6 +1000,9 @@
 e_mismatch_archive=$(gettext "Error: the archive top-level directory (%s) does not match the zonepath (%s).")
 e_tmpfile=$(gettext "Unable to create temporary file")
 e_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.")
+f_mkdir=$(gettext "Unable to create directory %s.")
+f_chmod=$(gettext "Unable to chmod directory %s.")
+f_chown=$(gettext "Unable to chown directory %s.")
 
 
 m_analyse_archive=$(gettext "Analysing the archive")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/native/zone/query.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,47 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+
+zonename=$1
+zonepath=$2
+cmd=$3
+
+if [ $3 == "datasets" ]; then
+	get_zonepath_ds $zonepath
+
+	DS=`/usr/sbin/zfs list -H -t filesystem -o name $ZONEPATH_DS/ROOT`
+	if [ ! -z "$DS" ]; then
+		echo "$DS\c"
+	else
+		fail_fatal "$f_no_ds"
+	fi
+fi
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/native/zone/uninstall.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,721 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# get script name (bname)
+#
+bname=`basename $0`
+
+#
+# common shell script functions
+#
+. /usr/lib/brand/shared/common.ksh
+
+#
+# error messages
+#
+m_usage=$(gettext "Usage: %s: [-hFn]")
+
+m_1_zfs_promote=$(gettext "promoting '%s'.")
+m_1_zfs_destroy=$(gettext "destroying '%s'.")
+m_2_zfs_rename=$(gettext "renaming '%s' to '%s'.")
+m_3_zfs_set=$(gettext "setting property %s='%s' for '%s'.")
+m_rm_r=$(gettext "recursively deleting '%s'.")
+m_rm=$(gettext "deleting '%s'.")
+
+w_no_ds=$(gettext "Warning: no zonepath dataset found.")
+
+f_usage_err=$(gettext "Error: invalid usage")
+f_abort=$(gettext "Error: internal error detected, aborting.")
+f_1_zfs_promote=$(gettext "Error: promoting ZFS dataset '%s'.")
+f_2_zfs_rename=$(gettext "Error: renaming ZFS dataset '%s' to '%s'.")
+f_3_zfs_set=$(gettext "Error: setting ZFS propery %s='%s' for '%s'.")
+f_1_zfs_destroy=$(gettext "Error: destroying ZFS dataset.")
+f_2_zfs_get=$(gettext "Error: reading ZFS dataset property '%s' from '%s'.")
+f_user_snap=$(gettext "Error: user snapshot(s) detected.")
+f_stray_snap=$(gettext "Error: uncloned snapshot(s) detected.")
+f_stray_clone=$(gettext "Error: cloned zone datasets found outsize of zone.")
+f_rm_snap=$(gettext "Error: please delete snapshot(s) and retry uninstall.")
+f_rm_clone=$(gettext "Error: please delete clone(s) and retry uninstall.")
+f_iu_clone=$(gettext "Error: cloned zone dataset(s) in use.")
+f_dis_clone=$(gettext "Error: please stop using clone(s) and retry uninstall.")
+
+#
+# functions
+#
+print_array()
+{
+	typeset -n pa_array=$1
+
+	(( pa_i = 0 ))
+	while (( $pa_i < ${#pa_array[@]} )); do
+		printf "\t${pa_array[$pa_i]}\n"
+		(( pa_i = $pa_i + 1 ))
+	done
+}
+
+usage()
+{
+	printf "$m_usage\n" "$bname"
+	exit $ZONE_SUBPROC_USAGE
+}
+
+usage_err()
+{
+	printf "$f_usage_err\n" >&2
+	usage >&2
+}
+
+rm_zonepath()
+{
+	# cleanup stuff we know about and leave any user data alone
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_rm\n" "$zonepath/SUNWattached.xml"
+	$nop /bin/rm -f "$zonepath/SUNWattached.xml"
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_rm_r\n" "$zonepath/lu"
+	$nop /bin/rm -rf "$zonepath/lu"
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_rm_r\n" "$zonepath/dev"
+	$nop /bin/rm -rf "$zonepath/dev"
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_rm_r\n" "$zonepath/root"
+	$nop /bin/rm -rf "$zonepath/root"
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_rm\n" "$zonepath"
+	$nop /bin/rmdir "$zonepath" 2>/dev/null
+}
+
+zfs_destroy()
+{
+	zd_fs1="$1"
+
+	# first figure out if the target fs has an origin snapshot
+	zd_origin=`/sbin/zfs get -H -o value origin "$zd_fs1"`
+	if [[ $? != 0 ]]; then
+		printf "$f_2_zfs_get\n" origin "$zd_fs1" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_1_zfs_destroy\n" "$zd_fs1"
+
+	#
+	# note that we specify the '-r' flag so that we destroy any
+	# descendants (filesystems and snapshot) of the specified
+	# filesystem.
+	#
+	$nop /sbin/zfs destroy -r "$zd_fs1"
+	if [[ $? != 0 ]]; then
+		printf "$f_1_zfs_destroy\n" "$zd_fs1" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	[[ "$zd_origin" == "-" ]] && return
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_1_zfs_destroy\n" "$zd_origin"
+
+	$nop /sbin/zfs destroy "$zd_origin" 2>/dev/null
+	#
+	# we ignore errors while trying to destroy the origin since
+	# the origin could have been used as the source for other
+	# clones
+	#
+}
+
+zfs_promote()
+{
+	zp_fs1="$1"
+
+	[[ -z "$opt_n" ]] &&
+		printf "$m_1_zfs_promote\n" "$zp_fs1"
+
+	$nop /sbin/zfs promote "$zp_fs1"
+	if [[ $? != 0 ]]; then
+		printf "$f_1_zfs_promote\n" "$zp_fs1" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+}
+
+zfs_rename()
+{
+	zr_fs1="$1"
+	zr_fs2="$2"
+
+	[[ -z "$opt_n" ]] &&
+		printf "$m_2_zfs_rename\n" "$zr_fs1" "$zr_fs2"
+
+	$nop /sbin/zfs rename "$zr_fs1" "$zr_fs2"
+	if [[ $? != 0 ]]; then
+		printf "$f_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" >&2
+		return 1
+	fi
+	return 0
+}
+
+zfs_set()
+{
+	zs_prop=$1
+	zs_value=$2
+	zs_fs1=$3
+
+	[[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
+		printf "$m_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1"
+
+	$nop /sbin/zfs set "$zs_prop"="$zs_value" "$zs_fs1"
+	if [[ $? != 0 ]]; then
+		printf "$f_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1"
+		return 1
+	fi
+	return 0
+}
+
+zfs_set_array()
+{
+	zsa_prop=$1
+	zsa_value=$2
+	typeset -n zsa_array=$3
+	zsa_ignore_errors=$4
+
+	(( zsa_i = 0 ))
+	while (( $zsa_i < ${#zsa_array[@]} )); do
+		zfs_set "$zsa_prop" "$zsa_value" "${zsa_array[$zsa_i]}"
+		[[ $? != 0 ]] && [[ -z "$zsa_ignore_errors" ]] &&
+			return 1
+		(( zsa_i = $zsa_i + 1 ))
+	done
+	return 0
+}
+
+
+(( snap_rename_zbe_i = 1 ))
+(( snap_rename_snap_i = 1 ))
+snap_rename_init()
+{
+	(( snap_rename_zbe_i = 1 ))
+	(( snap_rename_snap_i = 1 ))
+}
+
+snap_rename()
+{
+	eval sr_fs=\${$1}
+	eval sr_snap=\${$2}
+
+	if [[ "$sr_snap" == ~(Elr)(zbe-[0-9][0-9]*) ]]; then
+		sr_snap="zbe-$snap_rename_zbe_i"
+		(( snap_rename_zbe_i = $snap_rename_zbe_i + 1 ))
+	elif [[ "$sr_snap" == ~(Er)(_snap[0-9]*) ]]; then
+		sr_snap=${sr_snap##~(Er)([0-9]*)}
+		sr_snap="${sr_snap}${snap_rename_snap_i}"
+		(( snap_rename_snap_i = $snap_rename_snap_i + 1 ))
+	else
+		printf "$f_user_snap\n" >&2
+		printf "\t$sr_fs@$sr_snap\n" >&2
+		printf "$f_rm_snap\n" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	eval $2="$sr_snap"
+}
+
+# find the dataset associated with $zonepath
+uninstall_get_zonepath_ds()
+{
+	ZONEPATH_DS=`/sbin/zfs list -t filesystem -o name,mountpoint | \
+	    /bin/nawk -v zonepath=$zonepath '{
+		if ($2 == zonepath)
+			print $1
+	}'`
+
+	if [ -z "$ZONEPATH_DS" ]; then
+		# there is no $zonepath dataset
+		rm_zonepath
+		exit $ZONE_SUBPROC_OK
+	fi
+}
+
+# find the dataset associated with $ZONEPATH_DS/ROOT
+uninstall_get_zonepath_root_ds()
+{
+	ZONEPATH_RDS=`/sbin/zfs list -H -t filesystem -o name \
+		$ZONEPATH_DS/ROOT 2>/dev/null`
+
+	if [ -z "$ZONEPATH_RDS" ]; then
+		# there is no $ZONEPATH_DS/ROOT dataset
+		c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l`
+		if [ $c = 1 ]; then
+			# $zonepath dataset has no descendents
+			zfs_destroy "$ZONEPATH_DS"
+		fi
+		rm_zonepath
+		exit $ZONE_SUBPROC_OK
+	fi
+}
+
+destroy_zone_dataset()
+{
+	fs=$1
+
+	pool=${fs%%/*}
+
+	# Fastpath.  if there are no snapshots of $fs then just delete it.
+	c=`/sbin/zfs list -H -t snapshot -o name -r $fs | grep "^$fs@" |
+	    LC_ALL=C LANG=C wc -l`
+	if (( $c == 0 )) ; then
+		zfs_destroy "$fs"
+		return
+	fi
+
+	#
+	# This zone BE has snapshots.  This can happen if a zone has
+	# multiple BEs (in which case we have snapshots named "zbe-XXX"),
+	# if this zone has been used as the source for a clone of
+	# another zone (in which case we have snapshots named
+	# "XXX_snap"), or if an administrator has been doing manual
+	# snapshotting.
+	#
+	# To be able to destroy this dataset (which we'll call the
+	# origin) we need to get rid of all it's snapshots.  The "easiest"
+	# way to do this is to:
+	#
+	# - delete any uncloned origin snapshots
+	# - find the oldest clone of the youngest origin snapshot (which
+	#   we'll call the oldest clone)
+	# - check if there are any snapshots naming conflicts between
+	#   the origin and the oldest clone.
+	# - if so, find any clones of those conflicting origin snapshots
+	# - make sure that those clones are not zoned an in-use.
+	# - if any of those clones are zoned, unzone them.
+	# - rename origin snapshots to eliminate naming conflicts
+	# - for any clones that we unzoned, rezone them.
+	# - promote the oldest clone
+	# - destroy the origin and all it's descendants
+	#
+
+	#
+	# Get a list of all the cloned datasets within the zpool
+	# containing the origin filesystem.  Filter out any filesystems
+	# that are descendants of origin because we are planning to
+	# destroy them anyway.
+	#
+	unset clones clones_origin
+	(( clones_c = 0 ))
+	pool=${fs%%/*}
+	LANG=C LC_ALL=C /sbin/zfs list -H -t filesystem -s creation \
+	    -o name,origin -r "$pool" |
+	    while IFS="	" read name origin; do
+
+		# skip non-clone filesystems
+		[[ "$origin" == "-" ]] &&
+			continue
+
+		# skip desendents of the origin we plan to destroy
+		[[ "$name" == ~()(${fs}/*) ]] &&
+			continue
+
+		# record this clone and it's origin
+		clones[$clones_c]="$name"
+		clones_origin[$clones_c]="$origin"
+		(( clones_c = $clones_c + 1 ))
+	done
+
+	#
+	# Now do a sanity check.  Search for clones of a child datasets
+	# of the dataset we want to destroy, that are not themselves
+	# children of the dataset we're going to destroy).  This should
+	# really never happen unless the global zone admin has cloned a
+	# snapshot of a zone filesystem to a location outside of that
+	# zone.  bad admin...
+	#
+	unset stray_clones
+	(( stray_clones_c = 0 ))
+	(( j = 0 ))
+	while (( $j < $clones_c )); do
+		# is the clone origin a descendant of $fs?
+		if [[ "${clones_origin[$j]}" != ~()(${fs}/*) ]]; then
+			# we don't care.
+			(( j = $j + 1 ))
+			continue
+		fi
+		stray_clones[$stray_clones_c]=${clones[$j]}
+		(( stray_clones_c = $stray_clones_c + 1 ))
+		(( j = $j + 1 ))
+	done
+	if (( stray_clones_c > 0 )); then
+		#
+		# sigh.  the admin has done something strange.
+		# tell them to clean it up and retry.
+		#
+		printf "$f_stray_clone\n" >&2
+		print_array stray_clones >&2
+		printf "$f_rm_clone\n" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	# Find all the snapshots of the origin filesystem.
+	unset s_origin
+	(( s_origin_c = 0 ))
+	/sbin/zfs list -H -t snapshot -s creation -o name -r $fs |
+	    grep "^$fs@" | while read name; do
+		s_origin[$s_origin_c]=$name
+		(( s_origin_c = $s_origin_c + 1 ))
+	done
+
+	#
+	# Now go through the origin snapshots and find those which don't
+	# have clones.  We're going to explicity delete these snapshots
+	# before we do the promotion.
+	#
+	unset s_delete
+	(( s_delete_c = 0 ))
+	(( j = 0 ))
+	while (( $j < $s_origin_c )); do
+		(( k = 0 ))
+		while (( $k < $clones_c )); do
+			# if we have a match then break out of this loop
+			[[ "${s_origin[$j]}" == "${clones_origin[$k]}" ]] &&
+				break
+			(( k = $k + 1 ))
+		done
+		if (( $k != $clones_c )); then
+			# this snapshot has a clone, move on to the next one
+			(( j = $j + 1 ))
+			continue
+		fi
+
+		# snapshot has no clones so add it to our delete list
+		s_delete[$s_delete_c]=${s_origin[$j]}
+		(( s_delete_c = $s_delete_c + 1 ))
+		# remove it from the origin snapshot list
+		(( k = $j + 1 ))
+		while (( $k < $s_origin_c )); do
+			s_origin[(( $k - 1 ))]=${s_origin[$k]}
+			(( k = $k + 1 ))
+		done
+		(( s_origin_c = $s_origin_c - 1 ))
+	done
+
+	#
+	# Fastpath.  If there are no remaining snapshots then just
+	# delete the origin filesystem (and all it's descendents) and
+	# move onto the next zone BE.
+	#
+	if (( $s_origin_c == 0 )); then
+		zfs_destroy "$fs"
+		return
+	fi
+
+	# find the youngest snapshot of $fs
+	s_youngest=${s_origin[(( $s_origin_c - 1 ))]}
+
+	# Find the oldest clone of the youngest snapshot of $fs
+	unset s_clone
+	(( j = $clones_c - 1 ))
+	while (( $j >= 0 )); do
+		if [[ "$s_youngest" == "${clones_origin[$j]}" ]]; then
+			s_clone=${clones[$j]}
+			break
+		fi
+		(( j = $j - 1 ))
+	done
+	if [[ -z "$s_clone" ]]; then
+		# uh oh.  something has gone wrong.  bail.
+		printf "$f_stray_snap\n" >&2
+		printf "\t$s_youngest\n" >&2
+		printf "$f_rm_snap\n" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	# create an array of clone snapshot names
+	unset s_clone_s
+	(( s_clone_s_c = 0 ))
+	/sbin/zfs list -H -t snapshot -s creation -o name -r $s_clone |
+	    grep "^$s_clone@" | while read name; do
+		s_clone_s[$s_clone_s_c]=${name##*@}
+		(( s_clone_s_c = $s_clone_s_c + 1 ))
+	done
+
+	# create an arrays of possible origin snapshot renames
+	unset s_origin_snap
+	unset s_rename
+	(( j = 0 ))
+	while (( $j < $s_origin_c )); do
+		s_origin_snap[$j]=${s_origin[$j]##*@}
+		s_rename[$j]=${s_origin[$j]##*@}
+		(( j = $j + 1 ))
+	done
+
+	#
+	# Search for snapshot name collisions between the origin and
+	# oldest clone.  If we find one, generate a new name for the
+	# origin snapshot and re-do the collision check.
+	#
+	snap_rename_init
+	(( j = 0 ))
+	while (( $j < $s_origin_c )); do
+		(( k = 0 ))
+		while (( $k < $s_clone_s_c )); do
+
+			# if there's no naming conflict continue
+			if [[ "${s_rename[$j]}" != "${s_clone_s[$k]}" ]]; then
+				(( k = $k + 1 ))
+				continue
+			fi
+
+			#
+			# The origin snapshot conflicts with a clone
+			# snapshot.  Choose a new name and then restart
+			# then check that against clone snapshot names.
+			#
+			snap_rename fs "s_rename[$j]"
+			(( k = 0 ))
+			continue;
+		done
+
+		# if we didn't rename this snapshot then continue
+		if [[ "${s_rename[$j]}" == "${s_origin_snap[$j]}" ]]; then
+			(( j = $j + 1 ))
+			continue
+		fi
+
+		#
+		# We need to rename this origin snapshot because it
+		# conflicts with a clone snapshot name.  So above we
+		# chose a name that didn't conflict with any other clone
+		# snapshot names.  But we also have to avoid naming
+		# conflicts with any other origin snapshot names.  So
+		# check for that now.
+		#
+		(( k = 0 ))
+		while (( $k < $s_origin_c )); do
+
+			# don't compare against ourself
+			if (( $j == $k )); then
+				(( k = $k + 1 ))
+				continue
+			fi
+
+			# if there's no naming conflict continue
+			if [[ "${s_rename[$j]}" != "${s_rename[$k]}" ]]; then
+				(( k = $k + 1 ))
+				continue
+			fi
+
+			#
+			# The new origin snapshot name conflicts with
+			# another origin snapshot name.  Choose a new
+			# name and then go back to check the new name
+			# for uniqueness against all the clone snapshot
+			# names.
+			#
+			snap_rename fs "s_rename[$j]"
+			continue 2;
+		done
+
+		#
+		# A new unique name has been chosen.  Move on to the
+		# next origin snapshot.
+		#
+		(( j = $j + 1 ))
+		snap_rename_init
+	done
+
+	#
+	# So now we know what snapshots need to be renamed before the
+	# promotion.  But there's an additional problem.  If any of the
+	# filesystems cloned from these snapshots have the "zoned"
+	# attribute set (which is highly likely) or if they are in use
+	# (and can't be unmounted and re-mounted) then the snapshot
+	# rename will fail.  So now we'll search for all the clones of
+	# snapshots we plan to rename and look for ones that are zoned.
+	#
+	# We'll ignore any snapshot clones that may be in use but are
+	# not zoned.  If these clones are in-use, the rename will fail
+	# and we'll abort, there's not much else we can do about it.
+	# But if they are not in use the snapshot rename will unmount
+	# and remount the clone.  This is ok because when the zoned
+	# attribute is off, we know that the clone was originally
+	# mounted from the global zone.  (So unmounting and remounting
+	# it from the global zone is ok.)
+	#
+	# But we'll abort this whole operation if we find any clones
+	# that that are zoned and in use.  (This can happen if another
+	# zone has been cloned from this one and is now booted.)  The
+	# reason we do this is because those zoned filesystems could
+	# have originally mounted from within the zone.  So if we
+	# cleared the zone attribute and did the rename, we'd be
+	# remounting the filesystem from the global zone.  This would
+	# result in the zone losing the ability to unmount the
+	# filesystem, which would be bad.
+	#
+	unset zoned_clones zoned_iu_clones
+	(( zoned_clones_c = 0 ))
+	(( zoned_iu_clones_c = 0 ))
+	(( j = 0 ))
+	# walk through all the clones
+	while (( $j < $clones_c )); do
+		# walk through all the origin snapshots
+		(( k = 0 ))
+		while (( $k < $s_origin_c )); do
+			#
+			# check if this clone originated from a snapshot that
+			# we need to rename.
+			#
+			[[ "${clones_origin[$j]}" == "${s_origin[$k]}" ]] &&
+			    [[ "${s_origin_snap[$k]}" != "${s_rename[$k]}" ]] &&
+				break
+			(( k = $k + 1 ))
+			continue
+		done
+		if (( $k == $s_origin_c )); then
+			# This isn't a clone of a snapshot we want to rename.
+			(( j = $j + 1 ))
+			continue;
+		fi
+
+		# get the zoned attr for this clone.
+		zoned=`LC_ALL=C LANG=C \
+		    /sbin/zfs get -H -o value zoned ${clones[$j]}`
+		if [[ "$zoned" != on ]]; then
+			# This clone isn't zoned so ignore it.
+			(( j = $j + 1 ))
+			continue
+		fi
+
+		# remember this clone so we can muck with it's zoned attr.
+		zoned_clones[$zoned_clones_c]=${clones[$j]}
+		(( zoned_clones_c = $zoned_clones_c + 1 ))
+
+		# check if it's in use
+		mounted=`LC_ALL=C LANG=C \
+		    /sbin/zfs get -H -o value mounted ${clones[$j]}`
+		if [[ "$mounted" != yes ]]; then
+			# Good news.  This clone isn't in use.
+			(( j = $j + 1 ))
+			continue
+		fi
+
+		# Sigh.  This clone is in use so we're destined to fail.
+		zoned_iu_clones[$zoned_iu_clones_c]=${clones[$j]}
+		(( zoned_iu_clones_c = $zoned_iu_clones_c + 1 ))
+
+		# keep looking for errors so we can report them all at once.
+		(( j = $j + 1 ))
+	done
+	if (( zoned_iu_clones_c > 0 )); then
+		#
+		# Tell the admin
+		#
+		printf "$f_iu_clone\n" >&2
+		print_array zoned_iu_clones >&2
+		printf "$f_dis_clone\n" >&2
+		exit $ZONE_SUBPROC_FATAL
+	fi
+
+	#
+	# Ok.  So we're finally done with planning and we can do some
+	# damage.  We're going to:
+	# - destroy unused snapshots
+	# - unzone clones which originate from snapshots we need to rename
+	# - rename conflicting snapshots
+	# - rezone any clones which we unzoned
+	# - promote the oldest clone of the youngest snapshot
+	# - finally destroy the origin filesystem.
+	#
+
+	# delete any unsed snapshot
+	(( j = 0 ))
+	while (( $j < $s_delete_c )); do
+		zfs_destroy "${s_delete[$j]}"
+		(( j = $j + 1 ))
+	done
+
+	# unzone clones
+	zfs_set_array zoned off zoned_clones ||
+		zfs_set_array zoned on zoned_clones 1
+
+	# rename conflicting snapshots
+	(( j = 0 ))
+	while (( $j < $s_origin_c )); do
+		if [[ "${s_origin_snap[$j]}" != "${s_rename[$j]}" ]]; then
+			zfs_rename "${s_origin[$j]}" "$fs@${s_rename[$j]}"
+			if [[ $? != 0 ]]; then
+				# re-zone the clones before aborting
+				zfs_set_array zoned on zoned_clones 1
+				exit $ZONE_SUBPROC_FATAL
+			fi
+		fi
+		(( j = $j + 1 ))
+	done
+
+	# re-zone the clones
+	zfs_set_array zoned on zoned_clones 1
+
+	# promote the youngest clone of the oldest snapshot
+	zfs_promote "$s_clone"
+
+	# destroy the origin filesystem and it's descendants
+	zfs_destroy "$fs"
+}
+
+#
+# This function expects an array named fs_all to exist which is initialized
+# with the zone's ZFS datasets that should be destroyed.  fs_all_c is the
+# count of the number of elements in the array.  ZONEPATH_RDS is the
+# zonepath/root dataset and ZONEPATH_DS is the zonepath dataset.
+#
+destroy_zone_datasets()
+{
+	# Destroy the zone BEs datasets one by one.
+	(( i = 0 ))
+	while (( $i < $fs_all_c )); do
+		fs=${fs_all[$i]}
+
+		destroy_zone_dataset "$fs"
+		(( i = $i + 1 ))
+	done
+
+	#
+	# Check if there are any other datasets left.  There may be datasets
+	# associated with other GZ BEs, so we need to leave things alone in
+	# that case.
+	#
+	c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_RDS | wc -l`
+	if [ $c = 1 ]; then
+		zfs_destroy "$ZONEPATH_RDS"
+	fi
+	c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l`
+	if [ $c = 1 ]; then
+		zfs_destroy "$ZONEPATH_DS"
+	fi
+
+	rm_zonepath
+}
--- a/usr/src/lib/brand/sn1/librtld_db/Makefile.com	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/sn1/librtld_db/Makefile.com	Thu Oct 22 11:21:27 2009 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -52,9 +52,9 @@
 LDLIBS +=	-lc -lrtld_db
 CFLAGS +=	$(CCVERBOSE)
 CPPFLAGS +=	-D_REENTRANT -I../ -I$(UTSBASE)/common/brand/sn1 \
-			-I../../../../../cmd/sgs/librtld_db/common \
-			-I../../../../../cmd/sgs/include \
-			-I../../../../../cmd/sgs/include/$(MACH)
+			-I$(SRC)/cmd/sgs/librtld_db/common \
+			-I$(SRC)/cmd/sgs/include \
+			-I$(SRC)/cmd/sgs/include/$(MACH)
 
 ROOTLIBDIR =	$(ROOT)/usr/lib/brand/sn1
 ROOTLIBDIR64 =	$(ROOT)/usr/lib/brand/sn1/$(MACH64)
--- a/usr/src/lib/brand/sn1/sn1_brand/Makefile	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -19,15 +19,15 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
-include ../../../Makefile.lib
+include $(SRC)/lib/Makefile.lib
 
 default:	all
 
-SUBDIRS =	$(MACH) $(VARIANT_SUBDIRS)
+SUBDIRS =	$(MACH)
 $(BUILD64)SUBDIRS += $(MACH64)
 
 all :=		TARGET= all
@@ -39,9 +39,7 @@
 
 .KEEP_STATE:
 
-all install clean clobber _msg: $(SUBDIRS)
-
-lint: $(SUBDIRS)
+all install clean clobber lint _msg: $(SUBDIRS)
 
 $(SUBDIRS): FRC
 	@cd $@; pwd; $(MAKE) $(TARGET)
--- a/usr/src/lib/brand/sn1/zone/config.xml	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/sn1/zone/config.xml	Thu Oct 22 11:21:27 2009 -0700
@@ -59,6 +59,7 @@
 	<privilege set="default" name="net_bindmlp" />
 	<privilege set="default" name="net_icmpaccess" />
 	<privilege set="default" name="net_mac_aware" />
+	<privilege set="default" name="net_observability" />
 	<privilege set="default" name="net_privaddr" />
 	<privilege set="default" name="net_rawaccess" ip-type="exclusive" />
 	<privilege set="default" name="proc_chroot" />
--- a/usr/src/lib/brand/sn1/zone/platform.xml	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/lib/brand/sn1/zone/platform.xml	Thu Oct 22 11:21:27 2009 -0700
@@ -49,6 +49,7 @@
 
 	<!-- Devices to create under /dev -->
 	<device match="arp" />
+	<device match="bpf" />
 	<device match="conslog" />
 	<device match="cpu/self/cpuid" />
 	<device match="crypto" />
@@ -62,6 +63,7 @@
 	<device match="lo0" />
 	<device match="log" />
 	<device match="logindmux" />
+	<device match="nsmb" />
 	<device match="net/*" />
 	<device match="null" />
 	<device match="openprom" arch="sparc" />
@@ -120,7 +122,7 @@
 	<device match="spdsock" ip-type="exclusive" />
 	<device match="sppp" ip-type="exclusive" />
 	<device match="sppptun" ip-type="exclusive" />
-	
+
 	<!-- Renamed devices to create under /dev -->
 	<device match="zcons/%z/zoneconsole" name="zconsole" />
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+default: all
+
+include Makefile.s10
+
+# Build everything in parallel; use .WAIT for dependencies
+.PARALLEL:
+
+SUBDIRS =	librtld_db s10_npreload s10_brand s10_support zone cmd
+MSGSUBDIRS =	s10_support zone
+
+all :=		TARGET= all
+install :=	TARGET= install
+clean :=	TARGET= clean
+clobber :=	TARGET= clobber
+lint :=		TARGET= lint
+_msg :=		TARGET= _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MSGSUBDIRS)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/Makefile.s10	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# include global definitions
+
+BRAND =	solaris10
+
+include $(SRC)/lib/brand/Makefile.brand
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROGS =		s10_native s10_isaexec_wrapper s10_automount s10_automountd
+
+include $(SRC)/cmd/Makefile.cmd
+include ../Makefile.s10
+
+# override the install directory
+ROOTBIN =	$(ROOTBRANDDIR)
+CLOBBERFILES =	$(ROOTPROGS)
+
+.KEEP_STATE:
+
+all: $(PROGS)
+
+lint:
+
+install: all $(ROOTPROGS)
+
+clean:
+	$(RM) $(PROGS)
+
+include $(SRC)/cmd/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/s10_automount.sh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# All native executables must be run using the native linker.
+# By default, the kernel loads the linker at /lib/ld.so.1, which
+# in an s10 zone is the s10 linker.  Hence when we run the native
+# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our
+# linker.  For convience we define "n" to be the native path prefix.
+#
+n=/.SUNWnative
+LD_NOCONFIG=1
+LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps
+LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64
+LD_PRELOAD_32=s10_npreload.so.1
+LD_PRELOAD_64=s10_npreload.so.1
+export LD_NOCONFIG
+export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64
+exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \
+	/.SUNWnative/lib/ld.so.1 /.SUNWnative/usr/lib/fs/autofs/automount "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/s10_automountd.sh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# All native executables must be run using the native linker.
+# By default, the kernel loads the linker at /lib/ld.so.1, which
+# in an s10 zone is the s10 linker.  Hence when we run the native
+# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our
+# linker.  For convience we define "n" to be the native path prefix.
+#
+n=/.SUNWnative
+LD_NOCONFIG=1
+LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps
+LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64
+LD_PRELOAD_32=s10_npreload.so.1
+LD_PRELOAD_64=s10_npreload.so.1
+export LD_NOCONFIG
+export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64
+exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \
+	/.SUNWnative/lib/ld.so.1 /.SUNWnative/usr/lib/autofs/automountd "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/s10_isaexec_wrapper.sh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This script is invoked by isaexec-governed executable wrappers from within
+# s10-branded zones.  It circumvents the native isaexec so that native wrappers
+# will function correctly.
+#
+# All native executables must be run using the native linker.
+# By default, the kernel loads the linker at /lib/ld.so.1, which
+# in an s10 zone is the s10 linker.  Hence when we run the native
+# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our 32-
+# bit linker and /.SUNWnative/lib/64/ld.so.1 as our 64-bit linker.
+# For convience we define "n" to be the native path prefix.
+#
+bname=`/usr/bin/basename $0`
+dname=`/usr/bin/dirname $0`
+echo $dname | /usr/bin/grep "^/" >/dev/null || dname=`/bin/pwd`/$dname
+dname=`(cd $dname 2>/dev/null && /bin/pwd 2>/dev/null)`
+arch64=/
+LC_ALL=C /usr/bin/file /.SUNWnative/$dname/$bname | /usr/bin/grep "64-bit" \
+    >/dev/null && arch64=/64/
+n=/.SUNWnative
+
+LD_NOCONFIG=1
+LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps
+LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64
+LD_PRELOAD_32=s10_npreload.so.1
+LD_PRELOAD_64=s10_npreload.so.1
+export LD_NOCONFIG
+export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64
+exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \
+    /.SUNWnative/lib${arch64}ld.so.1 /.SUNWnative$dname/$bname "$@"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/s10_native.sh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#    
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#    
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+default: all
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+LINT_SUBDIRS=	$(MACH)
+$(BUILD64)LINT_SUBDIRS += $(MACH64)
+
+all :=          TARGET= all
+clean :=        TARGET= clean
+clobber :=      TARGET= clobber
+install :=      TARGET= install
+lint :=         TARGET= lint
+
+.KEEP_STATE:
+
+all install clean clobber: $(SUBDIRS)
+
+lint: $(LINT_SUBDIRS)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/Makefile.com	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,80 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY =	solaris10_librtld_db.a
+VERS	=	.1
+COBJS	=	solaris10_librtld_db.o
+OBJECTS	=	$(COBJS) $(COBJS64)
+
+include $(SRC)/lib/Makefile.lib
+include ../../Makefile.s10
+
+CSRCS =		$(COBJS:%o=../common/%c)
+SRCS  =		$(CSRCS)
+
+SRCDIR =	../common
+UTSBASE	=	$(SRC)/uts
+
+#
+# ATTENTION:
+#	Librtl_db brand plugin libraries should NOT directly invoke any
+#	libproc.so interfaces or be linked against libproc.  If a librtl_db
+#	brand plugin library uses libproc.so interfaces then it may break
+#	any other librtld_db consumers (like mdb) that tries to attach
+#	to a branded process.  The only safe interfaces that the a librtld_db
+#	brand plugin library can use to access a target process are the
+#	proc_service(3PROC) apis.
+#
+DYNFLAGS +=	$(VERSREF) -M../common/mapfile-vers
+LIBS =		$(DYNLIB)
+LDLIBS +=	-lc -lrtld_db
+CFLAGS +=	$(CCVERBOSE)
+CPPFLAGS +=	-D_REENTRANT -I../ -I$(UTSBASE)/common/brand/solaris10 \
+			-I$(SRC)/cmd/sgs/librtld_db/common \
+			-I$(SRC)/cmd/sgs/include \
+			-I$(SRC)/cmd/sgs/include/$(MACH)
+
+ROOTLIBDIR =	$(ROOT)/usr/lib/brand/solaris10
+ROOTLIBDIR64 =	$(ROOT)/usr/lib/brand/solaris10/$(MACH64)
+
+#
+# The top level Makefiles define define TEXT_DOMAIN.  But librtld_db.so.1
+# isn't internationalized and this library won't be either.  The only
+# messages that this library can generate are messages used for debugging
+# the operation of the library itself.
+#
+DTEXTDOM =
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+pics/%64.o:	../common/%.c
+		$(COMPILE.c) -D_ELF64 $(PICFLAGS) -o $@ $<
+		$(POST_PROCESS_O)
+
+include $(SRC)/lib/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/amd64/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+COBJS64 =	solaris10_librtld_db64.o
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+CLOBBERFILES =	$(ROOTLIBDIR64)/$(DYNLIB)
+DYNFLAGS +=	-M../common/mapfile-vers.64
+
+install: all $(ROOTLIBS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# MAPFILE HEADER START
+#
+# WARNING:  STOP NOW.  DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+#	usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+SUNWprivate_1.1 {
+	global:
+		rtld_db_brand_ops32;
+	local:
+		*;
+};
+
+#Externally defined symbols
+{
+    global:
+	ps_pauxv =		NODIRECT PARENT;
+	ps_pdmodel =		NODIRECT PARENT;
+	ps_pglobal_lookup =	NODIRECT PARENT;
+	ps_pglobal_sym =	NODIRECT PARENT;
+	ps_plog =		NODIRECT PARENT;
+	ps_pread =		NODIRECT PARENT;
+	ps_pwrite =		NODIRECT PARENT;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers.64	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# MAPFILE HEADER START
+#
+# WARNING:  STOP NOW.  DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+#	usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+SUNWprivate_1.1 {
+	global:
+		rtld_db_brand_ops64;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/common/solaris10_librtld_db.c	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,299 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <libproc.h>
+#include <proc_service.h>
+#include <synch.h>
+#include <sys/types.h>
+#include <sys/link.h>
+#include <rtld_db.h>
+
+#include <s10_brand.h>
+
+/*
+ * ATTENTION:
+ *	Librtl_db brand plugin libraries should NOT directly invoke any
+ *	libproc.so interfaces or be linked against libproc.  If a librtl_db
+ *	brand plugin library uses libproc.so interfaces then it may break
+ *	any other librtld_db consumers (like mdb) that tries to attach
+ *	to a branded process.  The only safe interfaces that the a librtld_db
+ *	brand plugin library can use to access a target process are the
+ *	proc_service(3PROC) apis.
+ */
+
+/*
+ * M_DATA comes from some streams header file but is also redifined in
+ * _rtld_db.h, so nuke the old streams definition here.
+ */
+#ifdef M_DATA
+#undef M_DATA
+#endif /* M_DATA */
+
+/*
+ * For 32-bit versions of this library, this file get's compiled once.
+ * For 64-bit versions of this library, this file get's compiled twice,
+ * once with _ELF64 defined and once without.  The expectation is that
+ * the 64-bit version of the library can properly deal with both 32-bit
+ * and 64-bit elf files, hence in the 64-bit library there are two copies
+ * of all the interfaces in this file, one set named *32 and one named *64.
+ *
+ * This also means that we need to be careful when declaring local pointers
+ * that point to objects in another processes address space, since these
+ * pointers may not match the current processes pointer width.  Basically,
+ * we should not use any objects that change size between 32 and 64 bit
+ * modes like: long, void *, uintprt_t, caddr_t, psaddr_t, size_t, etc.
+ * Instead we should declare all pointers as uint32_t.  Then when we
+ * are compiled to deal with 64-bit targets we'll re-define uing32_t
+ * to be a uint64_t.
+ */
+#ifdef _LP64
+#ifdef _ELF64
+#define	uint32_t			uint64_t
+#define	Elf32_Dyn			Elf64_Dyn
+#define	validate_rdebug32		validate_rdebug64
+#define	_rd_loadobj_iter32		_rd_loadobj_iter64
+#define	_rd_get_dyns32			_rd_get_dyns64
+#define	dummy_ldb32			dummy_ldb64
+#define	dummy_ldb_init32		dummy_ldb_init64
+#define	dummy_ldb_fini32		dummy_ldb_fini64
+#define	dummy_ldb_loadobj_iter32	dummy_ldb_loadobj_iter64
+#define	dummy_ldb_get_dyns32		dummy_ldb_get_dyns64
+#define	s10_ldb_init32			s10_ldb_init64
+#define	s10_ldb_fini32			s10_ldb_fini64
+#define	s10_ldb_loadobj_iter32		s10_ldb_loadobj_iter64
+#define	s10_ldb_get_dyns32		s10_ldb_get_dyns64
+#endif /* _ELF64 */
+#endif /* _LP64 */
+
+/* Included from usr/src/cmd/sgs/librtld_db/common */
+#include <_rtld_db.h>
+
+/*ARGSUSED*/
+static rd_helper_data_t
+dummy_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php)
+{
+	return (NULL);
+}
+
+/*ARGSUSED*/
+static void
+dummy_ldb_fini32(rd_helper_data_t rhd)
+{
+}
+
+/*ARGSUSED*/
+static int
+dummy_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data)
+{
+	return (RD_OK);
+}
+
+/*ARGSUSED*/
+static rd_err_e
+dummy_ldb_get_dyns32(rd_helper_data_t rhd,
+    psaddr_t addr, void **dynpp, size_t *dynpp_sz)
+{
+	*dynpp = NULL;
+	*dynpp_sz = 0;
+	return (RD_OK);
+}
+
+static rd_helper_ops_t dummy_ldb32 = {
+	LM_ID_BRAND,
+	dummy_ldb_init32,
+	dummy_ldb_fini32,
+	dummy_ldb_loadobj_iter32,
+	dummy_ldb_get_dyns32
+};
+
+static uint32_t
+s10_ldb_getauxval32(struct ps_prochandle *php, int type)
+{
+	const auxv_t		*auxvp = NULL;
+
+	if (ps_pauxv(php, &auxvp) != PS_OK)
+		return ((uint32_t)-1);
+
+	while (auxvp->a_type != AT_NULL) {
+		if (auxvp->a_type == type)
+			return ((uint32_t)(uintptr_t)auxvp->a_un.a_ptr);
+		auxvp++;
+	}
+	return ((uint32_t)-1);
+}
+
+/*
+ * Normally, the native Solaris librtldb_db plugin uses a bunch of different
+ * methods to try and find the rdebug structure associated with the target
+ * process we're debugging.  For details on the different methods see
+ * _rd_reset32().  Thankfully our job is easier.  We know that the brand
+ * library is always linked against the native linker, and when the
+ * process was first executed we saved off a pointer to the brand linkers
+ * rdebug structure in one of our brand specific aux vectors,
+ * AT_SUN_BRAND_S10_LDDATA.  So we'll just look that up here.
+ */
+/*ARGSUSED*/
+static rd_helper_data_t
+s10_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php)
+{
+	struct rd_agent	*rap_new;
+	uint32_t	lddata_addr;
+	int		rd_dmodel;
+
+	if (ps_pdmodel(php, &rd_dmodel) != PS_OK) {
+		ps_plog("s10_ldb_init: lookup of data model failed");
+		return (NULL);
+	}
+#ifdef _ELF64
+	assert(rd_dmodel == PR_MODEL_LP64);
+#else /* !_ELF64 */
+	assert(rd_dmodel == PR_MODEL_ILP32);
+#endif /* !_ELF64 */
+
+	lddata_addr = s10_ldb_getauxval32(php, AT_SUN_BRAND_S10_LDDATA);
+	if (lddata_addr == (uint32_t)-1) {
+		ps_plog("s10_ldb_init: no LDDATA found in aux vector");
+		return (NULL);
+	}
+	ps_plog("s10_ldb_init: found LDDATA auxv ld.so.1 data seg "
+	    "at: 0x%p", lddata_addr);
+
+	/*
+	 * Ok.  So this is kinda ugly.  Basically we know that we're going to
+	 * be parsing data from link maps that are generated by a Solaris
+	 * linker.  As it turns out, that's exactly what the default
+	 * Solaris librtld_db library is designed to do.  So rather than
+	 * duplicate all that link map parsing code here we'll simply
+	 * invoke the native librtld_db that normally does this, and when
+	 * we do we'll point them at our emulation libraries link map.
+	 *
+	 * Of course these interfacess aren't really public interfaces
+	 * and they take a "struct rd_agent" as a parameter.  So here
+	 * we'll allocate and initialize a new "struct rd_agent", point
+	 * it at our emulation libraries link map, and initialize just
+	 * enough of the structure to make the librtld_db interfaces
+	 * that we want to use happy.
+	 */
+	if ((rap_new = calloc(sizeof (*rap_new), 1)) == NULL) {
+		ps_plog("s10_ldb_init: can't allocate memory");
+		return (NULL);
+	}
+	rap_new->rd_dmodel = rd_dmodel;
+	rap_new->rd_psp = php;
+	rap_new->rd_rdebug = lddata_addr;
+	(void) mutex_init(&rap_new->rd_mutex, USYNC_THREAD, 0);
+
+	/*
+	 * When we get invoked from librtld_db, and we call back into it,
+	 * librtld_db will once again check if there is a plugin and
+	 * invoke it.  Since we don't want to enter a recursive loop
+	 * we're going to specify a different plugin interface for
+	 * our linkmap, and these new plugin interfaces won't actually
+	 * do anything other than return.
+	 */
+	rap_new->rd_helper.rh_ops = &dummy_ldb32;
+
+	/*
+	 * validate_rdebug32() requires the following "struct rd_agent"
+	 * members to be initialized:
+	 *	rd_psp, rd_rdebug
+	 *
+	 * validate_rdebug32() initializes the following "struct rd_agent"
+	 * members:
+	 *	rd_flags, rd_rdebugvers, rd_rtlddbpriv
+	 */
+	if (validate_rdebug32(rap_new) != RD_OK) {
+		ps_plog("s10_ldb_init: can't find valid r_debug data");
+		free(rap_new);
+		return (NULL);
+	}
+
+	ps_plog("s10_ldb_init: finished, helper_data=0x%p", rap_new);
+	return ((rd_helper_data_t)rap_new);
+}
+
+static void
+s10_ldb_fini32(rd_helper_data_t rhd)
+{
+	struct rd_agent	*rap = (struct rd_agent *)rhd;
+	ps_plog("s10_ldb_fini: cleaning up s10 helper");
+	free(rap);
+}
+
+/*ARGSUSED*/
+static int
+s10_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data)
+{
+	struct rd_agent	*rap = (struct rd_agent *)rhd;
+	int		err;
+
+	ps_plog("s10_ldb_loadobj_iter(helper_data=0x%p)", rhd);
+	assert(rap->rd_psp == php);
+	RDAGLOCK(rap);
+	/*
+	 * _rd_loadobj_iter32() requires the following "struct rd_agent"
+	 * members to be initialized:
+	 * 	rd_rtlddbpriv, rd_rdebugvers, rd_flags,
+	 * 	rd_helper.rh_ops, rd_dmodel
+	 */
+	err = _rd_loadobj_iter32(rap, cb, client_data);
+	RDAGUNLOCK(rap);
+	ps_plog("s10_ldb_loadobj_iter: finished, err = %d", err);
+	return (err);
+}
+
+/*ARGSUSED*/
+static rd_err_e
+s10_ldb_get_dyns32(rd_helper_data_t rhd,
+    psaddr_t addr, void **dynpp, size_t *dynpp_sz)
+{
+	struct rd_agent	*rap = (struct rd_agent *)rhd;
+	int		err;
+
+	ps_plog("s10_ldb_get_dyns(helper_data=0x%p)", rhd);
+	err = _rd_get_dyns32(rap, addr, (Elf32_Dyn **)dynpp, dynpp_sz);
+	ps_plog("s10_ldb_get_dyns: finished, err = %d", err);
+	return (err);
+}
+
+/*
+ * Librtld_db plugin linkage struct.
+ *
+ * When we get loaded by librtld_db, it will look for the symbol below
+ * to find our plugin entry points.
+ */
+rd_helper_ops_t RTLD_DB_BRAND_OPS = {
+	LM_ID_NONE,
+	s10_ldb_init32,
+	s10_ldb_fini32,
+	s10_ldb_loadobj_iter32,
+	s10_ldb_get_dyns32
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/i386/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+CLOBBERFILES =	$(ROOTLIBDIR)/$(DYNLIB)
+
+install: all $(ROOTLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/sparc/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+CLOBBERFILES =	$(ROOTLIBDIR)/$(DYNLIB)
+
+install: all $(ROOTLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/librtld_db/sparcv9/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+COBJS64 =	solaris10_librtld_db64.o
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+CLOBBERFILES =	$(ROOTLIBDIR64)/$(DYNLIB)
+DYNFLAGS +=	-M../common/mapfile-vers.64
+
+install: all $(ROOTLIBS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include $(SRC)/lib/Makefile.lib
+
+default:	all
+
+SUBDIRS =	$(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all :=		TARGET= all
+clean :=	TARGET= clean
+clobber :=	TARGET= clobber
+install :=	TARGET= install
+lint :=		TARGET= lint
+_msg :=		TARGET= _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint _msg: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/Makefile.com	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,119 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY =	s10_brand.a
+VERS =		.1
+COBJS =		s10_brand.o
+ASOBJS =	s10_crt.o s10_handler.o s10_runexe.o
+OFFSETS_SRC =	../common/offsets.in
+OFFSETS_H =	assym.h
+OBJECTS =	$(COBJS) $(ASOBJS)
+CLOBBERFILES +=	$(OFFSETS_H)
+
+include ../../Makefile.s10
+include $(SRC)/lib/Makefile.lib
+
+SRCDIR =	../common
+UTSBASE =	$(SRC)/uts
+
+LIBS =		$(DYNLIB)
+CSRCS =		$(COBJS:%o=../common/%c)
+ASSRCS =	$(ASOBJS:%o=$(ISASRCDIR)/%s)
+SRCS =		$(CSRCS) $(ASSRCS)
+
+#
+# Ugh, this is a gross hack.  Our assembly routines uses lots of defines
+# to simplify variable access.  All these defines work fine for amd64
+# compiles because when compiling for amd64 we use the GNU assembler,
+# gas.  For 32-bit code we use the Sun assembler, as.  Unfortunatly
+# as does not handle certian constructs that gas does.  So rather than
+# make our code less readable, we'll just use gas to compile our 32-bit
+# code as well.
+#
+i386_AS		= $(amd64_AS)
+
+#
+# Note that the architecture specific makefiles MUST update DYNFLAGS to
+# explicitly specify an interpreter for the brand emulation library so that we
+# use /lib/ld.so.1 or /lib/64/ld.so.1, which in a s10 zone is the Solaris 10
+# linker.  This is different from some other brands where the linker that is
+# used is the native system linker (/.SUNWnative/.../ld.so.1).  We have to do
+# this because the linker has a very incestuous relationship with libc and we
+# don't want to use the native linker with the s10 version of libc.  (This may
+# come as a surprise to the reader, but when our library is loaded it get's
+# linked against the s10 version of libc.)  Although the linker interfaces are
+# normally stable, there are examples, such as with the solaris8 brand, where
+# we could not combine the brand's libc with the native linker.  Since we want
+# to run in a known configuration, we use the S10 libc/linker combination.
+# 
+# There is one more non-obvious side effect of using the s10 linker that
+# should be mentioned.  Since the linker is used to setup processes before
+# libc is loaded, it makes system calls directly (ie avoiding libc), and
+# it makes these system calls before our library has been initialized.
+# Since our library hasn't been initialized yet, there's no way for us
+# to intercept and emulate any of those system calls.  So if any of those
+# system calls ever change in the native code such that they break the s10
+# linker then we're kinda screwed and will need to re-visit the current
+# solution.  (The likely solution then will probably be to start using the
+# native linker with our brand emulation library.)
+#
+# Note that we make sure to link our brand emulation library
+# libmapmalloc.  This is required because in most cases there will be two
+# copies of libc in the same process and we don't want them to fight over
+# the heap.  So for our brand library we link against libmapmalloc so that
+# if we (our or copy of libc) try to allocate any memory it will be done
+# via mmap() instead of brk().
+#
+CPPFLAGS +=	-D_REENTRANT -U_ASM \
+		-I. -I../sys -I$(UTSBASE)/common/brand/solaris10 \
+		-I$(SRC)/uts/common/fs/zfs
+CFLAGS +=	$(CCVERBOSE)
+# Needed to handle zfs include files
+C99MODE=	-xc99=%all
+C99LMODE=	-Xc99=%all
+ASFLAGS =	-P $(ASFLAGS_$(CURTYPE)) -D_ASM -I. -I../sys
+DYNFLAGS +=	$(DYNFLAGS_$(CLASS))
+DYNFLAGS +=	$(BLOCAL) $(ZNOVERSION) -Wl,-e_start
+LDLIBS +=	-lc -lmapmalloc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+#
+# build the offset header before trying to compile any files.  (it's included
+# by s10_misc.h, so it's needed for all objects, not just assembly ones.)
+#
+$(OBJECTS:%=pics/%): $(OFFSETS_H)
+$(OFFSETS_H): $(OFFSETS_SRC)
+	$(OFFSETS_CREATE) $(CTF_FLAGS) < $(OFFSETS_SRC) >$@
+
+pics/%.o: $(ISASRCDIR)/%.s
+	$(COMPILE.s) -o $@ $<
+	$(POST_PROCESS_O)
+
+include $(SRC)/lib/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+ISASRCDIR =		.
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+#
+# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter
+#
+# S10 linker
+DYNFLAGS +=		-Wl,-I/lib/64/ld.so.1
+CPPFLAGS += 		-D_SYSCALL32
+
+CLEANFILES +=		$(DYNLIB)
+CLOBBERFILES +=		$(ROOTLIBS64)
+
+install: all $(ROOTLIBS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_crt.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,73 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+
+#if defined(lint)
+
+void
+_start(void)
+{
+}
+
+#else	/* lint */
+	/*
+	 * Initial entry point for the brand emulation library.
+	 *
+	 * This platform specific assembly entry point exists just to invoke
+	 * the common brand library startup routine.  That routine expects to
+	 * be called with the following arguments:
+	 *	s10_init(int argc, char *argv[], char *envp[])
+	 *
+	 * There are no arguments explicitly passed to this entry point,
+	 * routine, but we do know how our initial stack has been setup by
+	 * the kernel.  The stack format is documented in:
+	 *	usr/src/cmd/sgs/rtld/amd64/boot.s
+	 *
+	 * So this routine will troll through the stack to setup the argument
+	 * values for the common brand library startup routine and then invoke
+	 * it.  This routine is modeled after the default crt1.s`_start()
+	 * routines.
+	 */
+	ENTRY_NP(_start)
+
+	/* Make stack traces look pretty, build a fake stack frame. */
+	pushq	$0			/ Build a stack frame. retpc = NULL
+	pushq	$0			/ fp = NULL
+	movq	%rsp, %rbp		/ first stack frame
+
+	/*
+	 * Calculate the location of the envp array by adding the size of
+	 * the argv array to the start of the argv array.
+	 */
+	movq	16(%rbp), %rdi		/ argc in %rax (1st param)
+	leaq	24(%rbp), %rsi		/ &argv[0] in %rbx (2nd param)
+	leaq	32(%rbp,%rdi,8), %rdx	/ envp in %rcx (3rd param)
+	call	s10_init
+
+	/*NOTREACHED*/
+	SET_SIZE(_start)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_handler.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,182 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <s10_misc.h>
+
+#if defined(lint)
+
+void
+s10_handler(void)
+{
+}
+
+#else	/* lint */
+	/*
+	 * %rax - syscall number
+	 * stack contains:
+	 *         --------------------------------------
+	 *    | 16 | syscall arguments			|
+	 *    v  8 | syscall wrapper return address	|
+	 *  %rsp+0 | syscall return address		|
+	 *         --------------------------------------
+	 */
+	ENTRY_NP(s10_handler)
+	pushq	%rbp			/* allocate stack frame */
+	movq	%rsp, %rbp
+
+	/* Save registers at the time of the syscall. */
+	movq	$0, EH_LOCALS_GREG(REG_TRAPNO)(%rbp)
+	movq	$0, EH_LOCALS_GREG(REG_ERR)(%rbp)
+	movq	%r15, EH_LOCALS_GREG(REG_R15)(%rbp)
+	movq	%r14, EH_LOCALS_GREG(REG_R14)(%rbp)
+	movq	%r13, EH_LOCALS_GREG(REG_R13)(%rbp)
+	movq	%r12, EH_LOCALS_GREG(REG_R12)(%rbp)
+	movq	%r11, EH_LOCALS_GREG(REG_R11)(%rbp)
+	movq	%r10, EH_LOCALS_GREG(REG_R10)(%rbp)
+	movq	%r9, EH_LOCALS_GREG(REG_R9)(%rbp)
+	movq	%r8, EH_LOCALS_GREG(REG_R8)(%rbp)
+	movq	%rdi, EH_LOCALS_GREG(REG_RDI)(%rbp)
+	movq	%rsi, EH_LOCALS_GREG(REG_RSI)(%rbp)
+	movq	%rax, EH_LOCALS_GREG(REG_RAX)(%rbp)
+	movq	%rbx, EH_LOCALS_GREG(REG_RBX)(%rbp)
+	movq	%rcx, EH_LOCALS_GREG(REG_RCX)(%rbp)
+	movq	%rdx, EH_LOCALS_GREG(REG_RDX)(%rbp)
+	xorq	%rcx, %rcx
+	movw	%cs, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_CS)(%rbp)
+	movw	%ds, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_DS)(%rbp)
+	movw	%es, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_ES)(%rbp)
+	movw	%fs, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_FS)(%rbp)
+	movw	%gs, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_GS)(%rbp)
+	movw	%ss, %cx
+	movq	%rcx, EH_LOCALS_GREG(REG_SS)(%rbp)
+	pushfq					/* save syscall flags */
+	popq	%r12
+	movq	%r12, EH_LOCALS_GREG(REG_RFL)(%rbp)
+	movq	EH_ARGS_OFFSET(0)(%rbp), %r12	/* save syscall rbp */
+	movq	%r12, EH_LOCALS_GREG(REG_RBP)(%rbp)
+	movq	%rbp, %r12			/* save syscall rsp */
+	addq	$CPTRSIZE, %r12
+	movq	%r12, EH_LOCALS_GREG(REG_RSP)(%rbp)
+	movq	EH_ARGS_OFFSET(1)(%rbp), %r12	/* save syscall ret address */
+	movq	%r12, EH_LOCALS_GREG(REG_RIP)(%rbp)
+	movq	%fs:0, %r12			/* save syscall fsbase */
+	movq	%r12, EH_LOCALS_GREG(REG_FSBASE)(%rbp)
+	movq	$0, EH_LOCALS_GREG(REG_GSBASE)(%rbp)
+
+	/*
+	 * Finish setting up our stack frame.  We would normally do this
+	 * upon entry to this function, but in this case we delayed it
+	 * because a "sub" operation can modify flags and we wanted to
+	 * save the flags into the gregset_t above before they get modified.
+	 *
+	 * Our stack frame format is documented in s10_misc.h.
+	 */
+	subq	$EH_LOCALS_SIZE, %rsp
+
+	/* Look up the system call's entry in the sysent table */
+	movq	s10_sysent_table@GOTPCREL(%rip), %r11 /* %r11 = sysent_table */
+	shlq	$4, %rax		/* each entry is 16 bytes */
+	addq	%rax, %r11		/* %r11 = sysent entry address */
+
+	/*
+	 * Get the return value flag and the number of arguments from the
+	 * sysent table.
+	 */
+	movq	CPTRSIZE(%r11), %r12		/* number of args + rv flag */
+	andq	$RV_MASK, %r12			/* strip out number of args */
+	movq	%r12, EH_LOCALS_RVFLAG(%rbp)	/* save rv flag */
+
+	/*
+	 * Setup arguments for our emulation call.  Our input arguments,
+	 * 0 to N, will become emulation call arguments 1 to N+1.
+	 *
+	 * Note: Syscall argument passing is different from function call
+	 * argument passing on amd64.  For function calls, the fourth arg
+	 * is passed via %rcx, but for system calls the 4th argument is
+	 * passed via %r10.  This is because in amd64, the syscall
+	 * instruction puts lower 32 bit of %rflags in %r11 and puts the
+	 * %rip value to %rcx.
+	 */
+	movq	EH_ARGS_OFFSET(4)(%rbp), %r12		/* copy 8th arg */
+	movq	%r12, EH_ARGS_OFFSET(2)(%rsp)
+	movq	EH_ARGS_OFFSET(3)(%rbp), %r12		/* copy 7th arg */
+	movq	%r12, EH_ARGS_OFFSET(1)(%rsp)
+	movq	%r9, EH_ARGS_OFFSET(0)(%rsp)
+	movq	%r8, %r9
+	movq	%r10, %r8
+	movq	%rdx, %rcx
+	movq	%rsi, %rdx
+	movq	%rdi, %rsi
+
+	/*
+	 * The first parameter to the emulation callback function is a
+	 * pointer to a sysret_t structure.
+	 */
+	movq	%rbp, %rdi
+	addq	$EH_LOCALS_SYSRET, %rdi		/* arg0 == sysret_t ptr */
+
+	/* invoke the emulation routine */
+	ALTENTRY(s10_handler_savepc)
+	call	*(%r11)
+
+	/* restore scratch and parameter registers */
+	movq	EH_LOCALS_GREG(REG_R12)(%rbp), %r12	/* restore %r12 */
+	movq	EH_LOCALS_GREG(REG_R11)(%rbp), %r11	/* restore %r11 */
+	movq	EH_LOCALS_GREG(REG_R10)(%rbp), %r10	/* restore %r10 */
+	movq	EH_LOCALS_GREG(REG_R9)(%rbp), %r9	/* restore %r9 */
+	movq	EH_LOCALS_GREG(REG_R8)(%rbp), %r8	/* restore %r8 */
+	movq	EH_LOCALS_GREG(REG_RCX)(%rbp), %rcx	/* restore %rcx */
+	movq	EH_LOCALS_GREG(REG_RDX)(%rbp), %rdx	/* restore %rdx */
+	movq	EH_LOCALS_GREG(REG_RSI)(%rbp), %rsi	/* restore %rsi */
+	movq	EH_LOCALS_GREG(REG_RDI)(%rbp), %rdi	/* restore %rdi */
+
+	/* Check for syscall emulation success or failure */
+	cmpq	$0, %rax
+	je	success
+	stc					/* failure, set carry flag */
+	jmp	return				/* return, %rax == errno */
+
+success:
+	/* There is always at least one return value. */
+	movq	EH_LOCALS_SYSRET1(%rbp), %rax	/* %rax == sys_rval1 */
+	cmpq	$RV_DEFAULT, EH_LOCALS_RVFLAG(%rbp) /* check rv flag */
+	je	clear_carry
+	mov	EH_LOCALS_SYSRET2(%rbp), %rdx	/* %rdx == sys_rval2 */
+clear_carry:
+	clc					/* success, clear carry flag */
+
+return:
+	movq	%rbp, %rsp			/* restore stack */
+	popq	%rbp
+	ret					/* ret to instr after syscall */
+	SET_SIZE(s10_handler)
+
+
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_runexe.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <s10_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+s10_runexe(void *argv, ulong_t entry)
+{
+}
+
+#else	/* lint */
+	/*
+	 * Prepare to jump to the target program we actually want to run.
+	 * If this program is dynamically linked then we'll be jumping to
+	 * another copy of the linker.  If it's a statically linked program
+	 * we'll be jumping directy to it's main entry point.  In any case,
+	 * we need to reset our current state stack and register state to
+	 * something similar to the initial process state setup by the kernel
+	 * and documented at:
+	 *	usr/src/cmd/sgs/rtld/i386/boot.s
+	 *	usr/src/cmd/sgs/rtld/sparcv9/boot.s
+	 *
+	 * Of course this is the same stack format as when this executable
+	 * was first started, so here we'll just roll back the stack and
+	 * frame pointers to their values when this processes first started
+	 * execution.
+	 */
+	ENTRY_NP(s10_runexe)
+
+	movq	%rdi, %rax		/ %rax = &argv[0]
+	movq	%rsi, %rbx		/ Brand app entry point in %rbx
+	subq	$8, %rax		/ Top of stack - must point at argc
+	movq	%rax, %rsp		/ Set %rsp to what linkers expect
+
+	/*
+	 * We also have to make sure to clear %rdx since nornally ld.so.1 will
+	 * set that to non-zero if there is an exit function that should be
+	 * invoked when the process is terminating.  This isn't actually
+	 * necessary if the target program we're jumping to is a dynamically
+	 * linked program since in that case we're actually jumping to another
+	 * copy of ld.so.1 and it will just reset %rdx, but if the target
+	 * program we're jumping to is a statically linked binary that uses
+	 * the standard sun compiler supplied crt1.o`_start(), it will check
+	 * to see if %g1 is set.
+	 */
+	movq	$0, %rdx
+
+	jmp	*%rbx			/ And away we go...
+	/*
+	 * target will never return.
+	 */
+	SET_SIZE(s10_runexe)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/common/mapfile-vers	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# MAPFILE HEADER START
+#
+# WARNING:  STOP NOW.  DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+#	usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+#
+# Scope everything local -- our .init section is our only public interface.
+#
+{
+	local:
+		*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/common/offsets.in	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,35 @@
+\
+\ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+\ Use is subject to license terms.
+\
+\ CDDL HEADER START
+\
+\ The contents of this file are subject to the terms of the
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
+\
+\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+\ or http://www.opensolaris.org/os/licensing.
+\ See the License for the specific language governing permissions
+\ and limitations under the License.
+\
+\ When distributing Covered Code, include this CDDL HEADER in each
+\ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+\ If applicable, add the following below this CDDL HEADER, with the
+\ fields enclosed by brackets "[]" replaced with your own identifying
+\ information: Portions Copyright [yyyy] [name of copyright owner]
+\
+\ CDDL HEADER END
+\
+
+
+#include <sys/types.h>
+#include <sys/regset.h>
+#include <sys/ucontext.h>
+#include <sys/syscall.h>
+
+greg_t		SIZEOF_GREG_T
+
+gregset_t	SIZEOF_GREGSET_T
+
+sysret_t	SIZEOF_SYSRET_T
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,1828 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <thread.h>
+#include <sys/auxv.h>
+#include <sys/bitmap.h>
+#include <sys/brand.h>
+#include <sys/inttypes.h>
+#include <sys/lwp.h>
+#include <sys/syscall.h>
+#include <sys/systm.h>
+#include <sys/utsname.h>
+#include <sys/systeminfo.h>
+#include <sys/zone.h>
+#include <sys/stat.h>
+#include <sys/mntent.h>
+#include <sys/ctfs.h>
+#include <sys/priv.h>
+#include <sys/acctctl.h>
+#include <libgen.h>
+#include <bsm/audit.h>
+#include <sys/crypto/ioctl.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_ioctl.h>
+#include <sys/ucontext.h>
+
+#include <s10_brand.h>
+#include <s10_misc.h>
+
+/*
+ * Principles of emulation 101.
+ *
+ *
+ * *** Setting errno
+ *
+ * Just don't do it.  This emulation library is loaded onto a
+ * seperate link map from the application who's address space we're
+ * running in.  We have our own private copy of libc, so there for,
+ * the errno value accessible from here is is also private and changing
+ * it will not affect any errno value that the processes who's address
+ * space we are running in will see.  To return an error condition we
+ * should return the negated errno value we'd like the system to return.
+ * For more information about this see the comment in s10_handler().
+ * Basically, when we return to the caller that initiated the system
+ * call it's their responsibility to set errno.
+ *
+ *
+ * *** Recursion Considerations
+ *
+ * When emulating system calls we need to be very careful about what
+ * library calls we invoke.  Library calls should be kept to a minimum.
+ * One issue is that library calls can invoke system calls, so if we're
+ * emulating a system call and we invoke a library call that depends on
+ * that system call we will probably enter a recursive loop, which would
+ * be bad.
+ *
+ *
+ * *** Return Values.
+ *
+ * When declaring new syscall emulation functions, it is very important
+ * to to set the proper RV_* flags in the s10_sysent_table.  Upon failure,
+ * syscall emulation fuctions should return an errno value.  Upon success
+ * syscall emulation functions should return 0 and set the sysret_t return
+ * value parameters accordingly.
+ *
+ * There are five possible syscall macro wrappers used in the kernel's system
+ * call sysent table.  These turn into the following return values:
+ *	SYSENT_CL	-> SYSENT_C or SYSENT_CI
+ *	SYSENT_C	SE_64RVAL		RV_DEFAULT
+ *	SYSENT_CI	SE_32RVAL1		RV_DEFAULT
+ *	SYSENT_2CI	SE_32RVAL1|SE_32RVAL2	RV_32RVAL2
+ *	SYSENT_AP	SE_64RVAL		RV_64RVAL
+ *
+ *
+ * *** Agent lwp considerations
+ *
+ * It is currently impossible to do any emulation for these system call
+ * when they are being invoked on behalf of an agent lwp.  To understand why
+ * it's impossible you have to understand how agent lwp syscalls work.
+ *
+ * The agent lwp syscall process works as follows:
+ *   1  The controlling process stops the target.
+ *   2  The controlling process injects an agent lwp which is also stopped.
+ *      This agent lwp assumes the userland stack and register values
+ *      of another stopped lwp in the current process.
+ *   3  The controlling process configures the agent lwp to start
+ *      executing the requested system call.
+ *   4  The controlling process configure /proc to stop the agent lwp when
+ *      it enters the requested system call.
+ *   5  The controlling processes allows the agent lwp to start executing.
+ *   6  The agent lwp traps into the kernel to perform the requested system
+ *      call and immediately stop.
+ *   7  The controlling process copies all the arguments for the requested
+ *      system call onto the agent lwp's stack.
+ *   8  The controlling process configures /proc to stop the agent lwp
+ *      when it completes the requested system call.
+ *   9  The controlling processes allows the agent lwp to start executing.
+ *  10  The agent lwp executes the system call and then stop before returning
+ *      to userland.
+ *  11  The controlling process copies the return value and return arguments
+ *      back from the agent lwps stack.
+ *  12  The controlling process destroys the agent lwp and restarts
+ *      the target process.
+ *
+ * The fundamental problem is that when the agent executes the request
+ * system call in step 5, if we're emulating that system call then the
+ * lwp is redirected back to our emulation layer without blocking
+ * in the kernel.  But our emulation layer can't access the arguments
+ * for the system call because they haven't been copied to the stack
+ * yet and they still only exist in the controlling processes address
+ * space.  This prevents us from being able to do any emulation of
+ * agent lwp system calls.  Hence, currently our brand trap interposition
+ * callback (s10_brand_syscall_callback_common) will detect if a system
+ * call is being made by an agent lwp, and if this is the case it will
+ * never redirect the system call to this emulation library.
+ *
+ * In the future, if this proves to be a problem the the easiest solution
+ * would probably be to replace the branded versions of these application
+ * with their native counterparts.  Ie,  truss, plimit, and pfiles could be
+ * replace with wrapper scripts that execute the native versions of these
+ * applications.  In the case of plimit and pfiles this should be pretty
+ * strait forward.  Truss would probably be more tricky since it can
+ * execute applications which would be branded applications, so in that
+ * case it might be necessary to create a loadable library which could
+ * be LD_PRELOADed into truss and this library would interpose on the
+ * exec() system call to allow truss to correctly execute branded
+ * processes.  It should be pointed out that this solution could work
+ * because "native agent lwps" (ie, agent lwps created by native
+ * processes) can be treated differently from "branded aged lwps" (ie,
+ * agent lwps created by branded processes), since native agent lwps
+ * would presumably be making native system calls and hence not need
+ * any interposition.
+ *
+ */
+
+static zoneid_t zoneid;
+static boolean_t emul_global_zone = B_FALSE;
+static int emul_vers;
+pid_t zone_init_pid;
+
+#define	EMULATE(cb, args)	{ (sysent_cb_t)(cb), (args) }
+#define	NOSYS			EMULATE(s10_unimpl, (0 | RV_DEFAULT))
+
+typedef long (*sysent_cb_t)();
+typedef struct s10_sysent_table {
+	sysent_cb_t	st_callc;
+	uintptr_t	st_args;
+} s10_sysent_table_t;
+s10_sysent_table_t s10_sysent_table[];
+
+#define	S10_UTS_RELEASE	"5.10"
+#define	S10_UTS_VERSION	"Generic_Virtual"
+
+/*LINTED: static unused*/
+static volatile int		s10_abort_err;
+/*LINTED: static unused*/
+static volatile const char	*s10_abort_msg;
+/*LINTED: static unused*/
+static volatile const char	*s10_abort_file;
+/*LINTED: static unused*/
+static volatile int		s10_abort_line;
+
+extern int errno;
+
+/*ARGSUSED*/
+void
+_s10_abort(int err, const char *msg, const char *file, int line)
+{
+	sysret_t rval;
+
+	/* Save the error message into convenient globals */
+	s10_abort_err = err;
+	s10_abort_msg = msg;
+	s10_abort_file = file;
+	s10_abort_line = line;
+
+	/* kill ourselves */
+	abort();
+
+	/* If abort() didn't work, try something stronger. */
+	(void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
+}
+
+static int
+s10_uucopy(const void *from, void *to, size_t size)
+{
+	sysret_t rval;
+
+	if (__systemcall(&rval, SYS_uucopy + 1024, from, to, size) != 0)
+		return (EFAULT);
+	return (0);
+}
+
+/*
+ * ATTENTION: uucopystr() does NOT ensure that string are null terminated!
+ */
+static int
+s10_uucopystr(const void *from, void *to, size_t size)
+{
+	sysret_t rval;
+
+	if (__systemcall(&rval, SYS_uucopystr + 1024, from, to, size) != 0)
+		return (EFAULT);
+	return (0);
+}
+
+/*
+ * Figures out the PID of init for the zone.  Also returns a boolean
+ * indicating whether this process currently has that pid: if so,
+ * then at this moment, we are init.
+ */
+static boolean_t
+get_initpid_info(void)
+{
+	pid_t pid;
+	sysret_t rval;
+	int err;
+
+	/*
+	 * Determine the current process PID and the PID of the zone's init.
+	 * We use care not to call getpid() here, because we're not supposed
+	 * to call getpid() until after the program is fully linked-- the
+	 * first call to getpid() is a signal from the linker to debuggers
+	 * that linking has been completed.
+	 */
+	if ((err = __systemcall(&rval, SYS_brand,
+	    B_S10_PIDINFO, &pid, &zone_init_pid)) != 0) {
+		s10_abort(err, "Failed to get init's pid");
+	}
+
+	/*
+	 * Note that we need to be cautious with the pid we get back--
+	 * it should not be stashed and used in place of getpid(), since
+	 * we might fork(2).  So we keep zone_init_pid and toss the pid
+	 * we otherwise got.
+	 */
+	if (pid == zone_init_pid)
+		return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+/*
+ * This function is defined to be NOSYS but it won't be called from the
+ * the kernel since the NOSYS system calls are not enabled in the kernel.
+ * Thus, the only time this function is called is directly from within the
+ * indirect system call path.
+ */
+/*ARGSUSED*/
+static long
+s10_unimpl(sysret_t *rv, uintptr_t p1)
+{
+	sysret_t rval;
+
+	/*
+	 * We'd like to print out some kind of error message here like
+	 * "unsupported syscall", but we can't because it's not safe to
+	 * assume that stderr or STDERR_FILENO actually points to something
+	 * that is a terminal, and if we wrote to those files we could
+	 * inadvertantly write to some applications open files, which would
+	 * be bad.
+	 *
+	 * Normally, if an application calls an invalid system call
+	 * it get a SIGSYS sent to it.  So we'll just go ahead and send
+	 * ourselves a signal here.  Note that this is far from ideal since
+	 * if the application has registered a signal handler, that signal
+	 * handler may recieve a ucontext_t as the third parameter to
+	 * indicate the context of the process when the signal was
+	 * generated, and in this case that context will not be what the
+	 * application is expecting.  Hence, we should probably create a
+	 * brandsys() kernel function that can deliver the signal to us
+	 * with the correct ucontext_t.
+	 */
+	(void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGSYS);
+	return (ENOSYS);
+}
+
+#if defined(__sparc) && !defined(__sparcv9)
+/*
+ * Yuck.  For 32-bit sparc applications, handle indirect system calls.
+ * Note that we declare this interface to use the maximum number of
+ * system call arguments.  If we recieve a system call that uses less
+ * arguments, then the additional arguments will be garbage, but they
+ * will also be ignored so that should be ok.
+ */
+static long
+s10_indir(sysret_t *rv, int code,
+    uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
+    uintptr_t a5, uintptr_t a6, uintptr_t a7)
+{
+	s10_sysent_table_t *sst = &(s10_sysent_table[code]);
+
+	s10_assert(code < NSYSCALL);
+	switch (sst->st_args & NARGS_MASK) {
+	case 0:
+		return ((sst->st_callc)(rv));
+	case 1:
+		return ((sst->st_callc)(rv, a0));
+	case 2:
+		return ((sst->st_callc)(rv, a0, a1));
+	case 3:
+		return ((sst->st_callc)(rv, a0, a1, a2));
+	case 4:
+		return ((sst->st_callc)(rv, a0, a1, a2, a3));
+	case 5:
+		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4));
+	case 6:
+		return ((sst->st_callc)(rv, rv, a0, a1, a2, a3, a4, a5));
+	case 7:
+		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6));
+	case 8:
+		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6, a7));
+	}
+	s10_abort(0, "invalid entry in s10_sysent_table");
+	return (EINVAL);
+}
+#endif /* __sparc && !__sparcv9 */
+
+/*
+ * Assign the structure member value from the s (source) structure to the
+ * d (dest) structure.
+ */
+#define	struct_assign(d, s, val)	(((d).val) = ((s).val))
+
+/*
+ * The CRYPTO_GET_FUNCTION_LIST parameter structure crypto_function_list_t
+ * changed between S10 and Nevada, so we have to emulate the old S10
+ * crypto_function_list_t structure when interposing on the ioctl syscall.
+ */
+typedef struct s10_crypto_function_list {
+	boolean_t fl_digest_init;
+	boolean_t fl_digest;
+	boolean_t fl_digest_update;
+	boolean_t fl_digest_key;
+	boolean_t fl_digest_final;
+
+	boolean_t fl_encrypt_init;
+	boolean_t fl_encrypt;
+	boolean_t fl_encrypt_update;
+	boolean_t fl_encrypt_final;
+
+	boolean_t fl_decrypt_init;
+	boolean_t fl_decrypt;
+	boolean_t fl_decrypt_update;
+	boolean_t fl_decrypt_final;
+
+	boolean_t fl_mac_init;
+	boolean_t fl_mac;
+	boolean_t fl_mac_update;
+	boolean_t fl_mac_final;
+
+	boolean_t fl_sign_init;
+	boolean_t fl_sign;
+	boolean_t fl_sign_update;
+	boolean_t fl_sign_final;
+	boolean_t fl_sign_recover_init;
+	boolean_t fl_sign_recover;
+
+	boolean_t fl_verify_init;
+	boolean_t fl_verify;
+	boolean_t fl_verify_update;
+	boolean_t fl_verify_final;
+	boolean_t fl_verify_recover_init;
+	boolean_t fl_verify_recover;
+
+	boolean_t fl_digest_encrypt_update;
+	boolean_t fl_decrypt_digest_update;
+	boolean_t fl_sign_encrypt_update;
+	boolean_t fl_decrypt_verify_update;
+
+	boolean_t fl_seed_random;
+	boolean_t fl_generate_random;
+
+	boolean_t fl_session_open;
+	boolean_t fl_session_close;
+	boolean_t fl_session_login;
+	boolean_t fl_session_logout;
+
+	boolean_t fl_object_create;
+	boolean_t fl_object_copy;
+	boolean_t fl_object_destroy;
+	boolean_t fl_object_get_size;
+	boolean_t fl_object_get_attribute_value;
+	boolean_t fl_object_set_attribute_value;
+	boolean_t fl_object_find_init;
+	boolean_t fl_object_find;
+	boolean_t fl_object_find_final;
+
+	boolean_t fl_key_generate;
+	boolean_t fl_key_generate_pair;
+	boolean_t fl_key_wrap;
+	boolean_t fl_key_unwrap;
+	boolean_t fl_key_derive;
+
+	boolean_t fl_init_token;
+	boolean_t fl_init_pin;
+	boolean_t fl_set_pin;
+
+	boolean_t prov_is_limited;
+	uint32_t prov_hash_threshold;
+	uint32_t prov_hash_limit;
+} s10_crypto_function_list_t;
+
+typedef struct s10_crypto_get_function_list {
+	uint_t				fl_return_value;
+	crypto_provider_id_t		fl_provider_id;
+	s10_crypto_function_list_t	fl_list;
+} s10_crypto_get_function_list_t;
+
+/*
+ * The structure returned by the CRYPTO_GET_FUNCTION_LIST ioctl on /dev/crypto
+ * increased in size due to:
+ *	6482533 Threshold for HW offload via PKCS11 interface
+ * between S10 and Nevada.  This is a relatively simple process of filling
+ * in the S10 structure fields with the Nevada data.
+ *
+ * We stat the device to make sure that the ioctl is meant for /dev/crypto.
+ *
+ */
+static int
+crypto_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
+{
+	int				err;
+	s10_crypto_get_function_list_t	s10_param;
+	crypto_get_function_list_t	native_param;
+	static dev_t			crypto_dev = (dev_t)-1;
+	struct stat			sbuf;
+
+	if (crypto_dev == (dev_t)-1) {
+		if ((err = __systemcall(rval, SYS_stat + 1024, "/dev/crypto",
+		    &sbuf)) != 0)
+			goto nonemuioctl;
+		crypto_dev = major(sbuf.st_rdev);
+	}
+	if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &sbuf)) != 0)
+		return (err);
+	/* Each open fd of /dev/crypto gets a new minor device. */
+	if (major(sbuf.st_rdev) != crypto_dev)
+		goto nonemuioctl;
+
+	if (s10_uucopy((const void *)arg, &s10_param, sizeof (s10_param)) != 0)
+		return (EFAULT);
+	struct_assign(native_param, s10_param, fl_provider_id);
+	if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd,
+	    &native_param)) != 0)
+		return (err);
+
+	struct_assign(s10_param, native_param, fl_return_value);
+	struct_assign(s10_param, native_param, fl_provider_id);
+
+	struct_assign(s10_param, native_param, fl_list.fl_digest_init);
+	struct_assign(s10_param, native_param, fl_list.fl_digest);
+	struct_assign(s10_param, native_param, fl_list.fl_digest_update);
+	struct_assign(s10_param, native_param, fl_list.fl_digest_key);
+	struct_assign(s10_param, native_param, fl_list.fl_digest_final);
+
+	struct_assign(s10_param, native_param, fl_list.fl_encrypt_init);
+	struct_assign(s10_param, native_param, fl_list.fl_encrypt);
+	struct_assign(s10_param, native_param, fl_list.fl_encrypt_update);
+	struct_assign(s10_param, native_param, fl_list.fl_encrypt_final);
+
+	struct_assign(s10_param, native_param, fl_list.fl_decrypt_init);
+	struct_assign(s10_param, native_param, fl_list.fl_decrypt);
+	struct_assign(s10_param, native_param, fl_list.fl_decrypt_update);
+	struct_assign(s10_param, native_param, fl_list.fl_decrypt_final);
+
+	struct_assign(s10_param, native_param, fl_list.fl_mac_init);
+	struct_assign(s10_param, native_param, fl_list.fl_mac);
+	struct_assign(s10_param, native_param, fl_list.fl_mac_update);
+	struct_assign(s10_param, native_param, fl_list.fl_mac_final);
+
+	struct_assign(s10_param, native_param, fl_list.fl_sign_init);
+	struct_assign(s10_param, native_param, fl_list.fl_sign);
+	struct_assign(s10_param, native_param, fl_list.fl_sign_update);
+	struct_assign(s10_param, native_param, fl_list.fl_sign_final);
+	struct_assign(s10_param, native_param, fl_list.fl_sign_recover_init);
+	struct_assign(s10_param, native_param, fl_list.fl_sign_recover);
+
+	struct_assign(s10_param, native_param, fl_list.fl_verify_init);
+	struct_assign(s10_param, native_param, fl_list.fl_verify);
+	struct_assign(s10_param, native_param, fl_list.fl_verify_update);
+	struct_assign(s10_param, native_param, fl_list.fl_verify_final);
+	struct_assign(s10_param, native_param, fl_list.fl_verify_recover_init);
+	struct_assign(s10_param, native_param, fl_list.fl_verify_recover);
+
+	struct_assign(s10_param, native_param,
+	    fl_list.fl_digest_encrypt_update);
+	struct_assign(s10_param, native_param,
+	    fl_list.fl_decrypt_digest_update);
+	struct_assign(s10_param, native_param, fl_list.fl_sign_encrypt_update);
+	struct_assign(s10_param, native_param,
+	    fl_list.fl_decrypt_verify_update);
+
+	struct_assign(s10_param, native_param, fl_list.fl_seed_random);
+	struct_assign(s10_param, native_param, fl_list.fl_generate_random);
+
+	struct_assign(s10_param, native_param, fl_list.fl_session_open);
+	struct_assign(s10_param, native_param, fl_list.fl_session_close);
+	struct_assign(s10_param, native_param, fl_list.fl_session_login);
+	struct_assign(s10_param, native_param, fl_list.fl_session_logout);
+
+	struct_assign(s10_param, native_param, fl_list.fl_object_create);
+	struct_assign(s10_param, native_param, fl_list.fl_object_copy);
+	struct_assign(s10_param, native_param, fl_list.fl_object_destroy);
+	struct_assign(s10_param, native_param, fl_list.fl_object_get_size);
+	struct_assign(s10_param, native_param,
+	    fl_list.fl_object_get_attribute_value);
+	struct_assign(s10_param, native_param,
+	    fl_list.fl_object_set_attribute_value);
+	struct_assign(s10_param, native_param, fl_list.fl_object_find_init);
+	struct_assign(s10_param, native_param, fl_list.fl_object_find);
+	struct_assign(s10_param, native_param, fl_list.fl_object_find_final);
+
+	struct_assign(s10_param, native_param, fl_list.fl_key_generate);
+	struct_assign(s10_param, native_param, fl_list.fl_key_generate_pair);
+	struct_assign(s10_param, native_param, fl_list.fl_key_wrap);
+	struct_assign(s10_param, native_param, fl_list.fl_key_unwrap);
+	struct_assign(s10_param, native_param, fl_list.fl_key_derive);
+
+	struct_assign(s10_param, native_param, fl_list.fl_init_token);
+	struct_assign(s10_param, native_param, fl_list.fl_init_pin);
+	struct_assign(s10_param, native_param, fl_list.fl_set_pin);
+
+	struct_assign(s10_param, native_param, fl_list.prov_is_limited);
+	struct_assign(s10_param, native_param, fl_list.prov_hash_threshold);
+	struct_assign(s10_param, native_param, fl_list.prov_hash_limit);
+
+	return (s10_uucopy(&s10_param, (void *)arg, sizeof (s10_param)));
+
+nonemuioctl:
+	return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
+}
+
+/*
+ * The process contract CT_TGET and CT_TSET parameter structure ct_param_t
+ * changed between S10 and Nevada, so we have to emulate the old S10
+ * ct_param_t structure when interposing on the ioctl syscall.
+ */
+typedef struct s10_ct_param {
+	uint32_t ctpm_id;
+	uint32_t ctpm_pad;
+	uint64_t ctpm_value;
+} s10_ct_param_t;
+
+/*
+ * We have to emulate process contract ioctls for init(1M) because the
+ * ioctl parameter structure changed between S10 and Nevada.  This is
+ * a relatively simple process of filling Nevada structure fields,
+ * shuffling values, and initiating a native system call.
+ *
+ * For now, we'll assume that all consumers of CT_TGET and CT_TSET will
+ * need emulation.  We'll issue a stat to make sure that the ioctl
+ * is meant for the contract file system.
+ *
+ */
+static int
+ctfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
+{
+	int err;
+	s10_ct_param_t s10param;
+	ct_param_t param;
+	struct stat statbuf;
+
+	if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &statbuf)) != 0)
+		return (err);
+	if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0)
+		return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
+
+	if (s10_uucopy((const void *)arg, &s10param, sizeof (s10param)) != 0)
+		return (EFAULT);
+	param.ctpm_id = s10param.ctpm_id;
+	param.ctpm_size = sizeof (uint64_t);
+	param.ctpm_value = &s10param.ctpm_value;
+	if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &param))
+	    != 0)
+		return (err);
+
+	if (cmd == CT_TGET)
+		return (s10_uucopy(&s10param, (void *)arg, sizeof (s10param)));
+
+	return (0);
+}
+
+typedef struct s10_zfs_cmd {
+	char		zc_name[MAXPATHLEN];
+	char		zc_value[MAXPATHLEN * 2];
+	char		zc_string[MAXNAMELEN];
+	uint64_t	zc_guid;
+	uint64_t	zc_nvlist_conf;		/* really (char *) */
+	uint64_t	zc_nvlist_conf_size;
+	uint64_t	zc_nvlist_src;		/* really (char *) */
+	uint64_t	zc_nvlist_src_size;
+	uint64_t	zc_nvlist_dst;		/* really (char *) */
+	uint64_t	zc_nvlist_dst_size;
+	uint64_t	zc_cookie;
+	uint64_t	zc_objset_type;
+	uint64_t	zc_perm_action;
+	uint64_t 	zc_history;		/* really (char *) */
+	uint64_t 	zc_history_len;
+	uint64_t	zc_history_offset;
+	uint64_t	zc_obj;
+	/* Solaris Next added zc_iflags member here */
+	zfs_share_t	zc_share;
+	dmu_objset_stats_t zc_objset_stats;
+	struct drr_begin zc_begin_record;
+	zinject_record_t zc_inject_record;
+} s10_zfs_cmd_t;
+
+/*
+ * There is a difference in the zfs_cmd_t ioctl parameter between S10 and
+ * Solaris Next so we need to translate between the two structures when
+ * making ZFS ioctls.
+ */
+static int
+zfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
+{
+	int				err;
+	s10_zfs_cmd_t			s10_param;
+	zfs_cmd_t			native_param;
+	static dev_t			zfs_dev = (dev_t)-1;
+	struct stat			sbuf;
+
+	if (zfs_dev == (dev_t)-1) {
+		if ((err = __systemcall(rval, SYS_stat + 1024, "/dev/zfs",
+		    &sbuf)) != 0)
+			goto nonemuioctl;
+		zfs_dev = major(sbuf.st_rdev);
+	}
+	if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &sbuf)) != 0)
+		return (err);
+	if (major(sbuf.st_rdev) != zfs_dev)
+		goto nonemuioctl;
+
+	if (s10_uucopy((const void *)arg, &s10_param, sizeof (s10_param)) != 0)
+		return (EFAULT);
+
+	bcopy((const void *)s10_param.zc_name, (void *)native_param.zc_name,
+	    sizeof (s10_param.zc_name));
+	bcopy((const void *)s10_param.zc_value, (void *)native_param.zc_value,
+	    sizeof (s10_param.zc_value));
+	bcopy((const void *)s10_param.zc_string, (void *)native_param.zc_string,
+	    sizeof (s10_param.zc_string));
+	struct_assign(native_param, s10_param, zc_guid);
+	struct_assign(native_param, s10_param, zc_nvlist_conf);
+	struct_assign(native_param, s10_param, zc_nvlist_conf_size);
+	struct_assign(native_param, s10_param, zc_nvlist_src);
+	struct_assign(native_param, s10_param, zc_nvlist_src_size);
+	struct_assign(native_param, s10_param, zc_nvlist_dst);
+	struct_assign(native_param, s10_param, zc_nvlist_dst_size);
+	struct_assign(native_param, s10_param, zc_cookie);
+	struct_assign(native_param, s10_param, zc_objset_type);
+	struct_assign(native_param, s10_param, zc_perm_action);
+	struct_assign(native_param, s10_param, zc_history);
+	struct_assign(native_param, s10_param, zc_history_len);
+	struct_assign(native_param, s10_param, zc_history_offset);
+	struct_assign(native_param, s10_param, zc_obj);
+	native_param.zc_iflags = 0;
+	struct_assign(native_param, s10_param, zc_share);
+	struct_assign(native_param, s10_param, zc_objset_stats);
+	struct_assign(native_param, s10_param, zc_begin_record);
+	struct_assign(native_param, s10_param, zc_inject_record);
+
+	err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &native_param);
+
+	bcopy((const void *)native_param.zc_name, (void *)s10_param.zc_name,
+	    sizeof (s10_param.zc_name));
+	bcopy((const void *)native_param.zc_value, (void *)s10_param.zc_value,
+	    sizeof (s10_param.zc_value));
+	bcopy((const void *)native_param.zc_string, (void *)s10_param.zc_string,
+	    sizeof (s10_param.zc_string));
+	struct_assign(s10_param, native_param, zc_guid);
+	struct_assign(s10_param, native_param, zc_nvlist_conf);
+	struct_assign(s10_param, native_param, zc_nvlist_conf_size);
+	struct_assign(s10_param, native_param, zc_nvlist_src);
+	struct_assign(s10_param, native_param, zc_nvlist_src_size);
+	struct_assign(s10_param, native_param, zc_nvlist_dst);
+	struct_assign(s10_param, native_param, zc_nvlist_dst_size);
+	struct_assign(s10_param, native_param, zc_cookie);
+	struct_assign(s10_param, native_param, zc_objset_type);
+	struct_assign(s10_param, native_param, zc_perm_action);
+	struct_assign(s10_param, native_param, zc_history);
+	struct_assign(s10_param, native_param, zc_history_len);
+	struct_assign(s10_param, native_param, zc_history_offset);
+	struct_assign(s10_param, native_param, zc_obj);
+	struct_assign(s10_param, native_param, zc_share);
+	struct_assign(s10_param, native_param, zc_objset_stats);
+	struct_assign(s10_param, native_param, zc_begin_record);
+	struct_assign(s10_param, native_param, zc_inject_record);
+
+	(void) s10_uucopy(&s10_param, (void *)arg, sizeof (s10_param));
+	return (err);
+
+nonemuioctl:
+	return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
+}
+
+int
+s10_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
+{
+	switch (cmd) {
+	case CRYPTO_GET_FUNCTION_LIST:
+		return (crypto_ioctl(rval, fdes, cmd, arg));
+	case CT_TGET:
+		/*FALLTHRU*/
+	case CT_TSET:
+		return (ctfs_ioctl(rval, fdes, cmd, arg));
+	}
+
+	if ((cmd & 0xff00) == ZFS_IOC)
+		return (zfs_ioctl(rval, fdes, cmd, arg));
+
+	return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
+}
+
+/*
+ * Unfortunately, pwrite()'s behavior differs between S10 and Nevada when
+ * applied to files opened with O_APPEND.  The offset argument is ignored and
+ * the buffer is appended to the target file in S10, whereas the current file
+ * position is ignored in Nevada (i.e., pwrite() acts as though the target file
+ * wasn't opened with O_APPEND).  This is a result of the fix for CR 6655660
+ * (pwrite() must ignore the O_APPEND/FAPPEND flag).
+ *
+ * We emulate the old S10 pwrite() behavior by checking whether the target file
+ * was opened with O_APPEND.  If it was, then invoke the write() system call
+ * instead of pwrite(); otherwise, invoke the pwrite() system call as usual.
+ */
+static int
+s10_pwrite(sysret_t *rval, int fd, const void *bufferp, size_t num_bytes,
+    off_t offset)
+{
+	int err;
+
+	if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
+		return (err);
+	if (rval->sys_rval1 & O_APPEND)
+		return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
+		    num_bytes));
+	return (__systemcall(rval, SYS_pwrite + 1024, fd, bufferp, num_bytes,
+	    offset));
+}
+
+#ifndef	_LP64
+/*
+ * This is the large file version of the pwrite() system call for 32-bit
+ * processes.  This exists for the same reason that s10_pwrite() exists; see
+ * the comment above s10_pwrite().
+ */
+static int
+s10_pwrite64(sysret_t *rval, int fd, const void *bufferp, size32_t num_bytes,
+    uint32_t offset_1, uint32_t offset_2)
+{
+	int err;
+
+	if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
+		return (err);
+	if (rval->sys_rval1 & O_APPEND)
+		return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
+		    num_bytes));
+	return (__systemcall(rval, SYS_pwrite64 + 1024, fd, bufferp,
+	    num_bytes, offset_1, offset_2));
+}
+#endif	/* !_LP64 */
+
+#define	S10_AC_PROC		(0x1 << 28)
+#define	S10_AC_TASK		(0x2 << 28)
+#define	S10_AC_FLOW		(0x4 << 28)
+#define	S10_AC_MODE(x)		((x) & 0xf0000000)
+#define	S10_AC_OPTION(x)	((x) & 0x0fffffff)
+
+/*
+ * The mode shift, mode mask and option mask for acctctl have changed.  The
+ * mode is currently the top full byte and the option is the lower 3 full bytes.
+ */
+int
+s10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz)
+{
+	int mode = S10_AC_MODE(cmd);
+	int option = S10_AC_OPTION(cmd);
+
+	switch (mode) {
+	case S10_AC_PROC:
+		mode = AC_PROC;
+		break;
+	case S10_AC_TASK:
+		mode = AC_TASK;
+		break;
+	case S10_AC_FLOW:
+		mode = AC_FLOW;
+		break;
+	default:
+		return (S10_TRUSS_POINT_3(rval, SYS_acctctl, EINVAL, cmd, buf,
+		    bufsz));
+	}
+
+	return (__systemcall(rval, SYS_acctctl + 1024, mode | option, buf,
+	    bufsz));
+}
+
+/*
+ * The Audit Policy parameters have changed due to:
+ *    6466722 audituser and AUDIT_USER are defined, unused, undocumented and
+ *            should be removed.
+ *
+ * In S10 we had the following flag:
+ *	#define AUDIT_USER 0x0040
+ * which doesn't exist in Solaris Next where the subsequent flags are shifted
+ * down.  For example, in S10 we had:
+ *	#define AUDIT_GROUP     0x0080
+ * but on Solaris Next we have:
+ *	#define AUDIT_GROUP     0x0040
+ * AUDIT_GROUP has the value AUDIT_USER had in S10 and all of the subsequent
+ * bits are also shifted one place.
+ *
+ * When we're getting or setting the Audit Policy parameters we need to
+ * shift the outgoing or incoming bits into their proper positions.  Since
+ * S10_AUDIT_USER was always unused, we always clear that bit on A_GETPOLICY.
+ *
+ * The command we care about, BSM_AUDITCTL, passes the most parameters (3),
+ * so declare this function to take up to 4 args and just pass them on.
+ * The number of parameters for s10_auditsys needs to be equal to the BSM_*
+ * subcommand that has the most parameters, since we want to pass all
+ * parameters through, regardless of which subcommands we interpose on.
+ *
+ * Note that the auditsys system call uses the SYSENT_AP macro wrapper instead
+ * of the more common SYSENT_CI macro.  This means the return value is a
+ * SE_64RVAL so the syscall table uses RV_64RVAL.
+ */
+
+#define	S10_AUDIT_HMASK	0xffffffc0
+#define	S10_AUDIT_LMASK	0x3f
+
+int
+s10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2)
+{
+	int	err;
+	uint_t	m;
+
+	if (bsmcmd != BSM_AUDITCTL)
+		return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1,
+		    a2));
+
+	if ((int)a0 == A_GETPOLICY) {
+		if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
+		    &m, a2)) != 0)
+			return (err);
+		m = ((m & S10_AUDIT_HMASK) << 1) | (m & S10_AUDIT_LMASK);
+		if (s10_uucopy(&m, (void *)a1, sizeof (m)) != 0)
+			return (EFAULT);
+		return (0);
+
+	} else if ((int)a0 == A_SETPOLICY) {
+		if (s10_uucopy((const void *)a1, &m, sizeof (m)) != 0)
+			return (EFAULT);
+		m = ((m >> 1) & S10_AUDIT_HMASK) | (m & S10_AUDIT_LMASK);
+		return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
+		    a2));
+	}
+
+	return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, a2));
+}
+
+/*
+ * Determine whether the executable passed to SYS_exec or SYS_execve is a
+ * native executable.  The s10_npreload.so invokes the B_S10_NATIVE brand
+ * operation which patches up the processes exec info to eliminate any trace
+ * of the wrapper.  That will make pgrep and other commands that examine
+ * process' executable names and command-line parameters work properly.
+ */
+static int
+s10_exec_native(sysret_t *rval, const char *fname, const char **argp,
+    const char **envp)
+{
+	const char *filename = fname;
+	char path[64];
+	int err;
+
+	/* Get a copy of the executable we're trying to run */
+	path[0] = '\0';
+	(void) s10_uucopystr(filename, path, sizeof (path));
+
+	/* Check if we're trying to run a native binary */
+	if (strncmp(path, "/.SUNWnative/usr/lib/brand/solaris10/s10_native",
+	    sizeof (path)) != 0)
+		return (0);
+
+	/* Skip the first element in the argv array */
+	argp++;
+
+	/*
+	 * The the path of the dynamic linker is the second parameter
+	 * of s10_native_exec().
+	 */
+	if (s10_uucopy(argp, &filename, sizeof (char *)) != 0)
+		return (EFAULT);
+
+	/* If an exec call succeeds, it never returns */
+	err = __systemcall(rval, SYS_brand + 1024, B_EXEC_NATIVE, filename,
+	    argp, envp, NULL, NULL, NULL);
+	s10_assert(err != 0);
+	return (err);
+}
+
+/*
+ * Interpose on the SYS_exec syscall to detect native wrappers.
+ */
+int
+s10_exec(sysret_t *rval, const char *fname, const char **argp)
+{
+	int err;
+
+	if ((err = s10_exec_native(rval, fname, argp, NULL)) != 0)
+		return (err);
+
+	/* If an exec call succeeds, it never returns */
+	err = __systemcall(rval, SYS_exec + 1024, fname, argp);
+	s10_assert(err != 0);
+	return (err);
+}
+
+/*
+ * Interpose on the SYS_execve syscall to detect native wrappers.
+ */
+int
+s10_execve(sysret_t *rval, const char *fname, const char **argp,
+    const char **envp)
+{
+	int err;
+
+	if ((err = s10_exec_native(rval, fname, argp, envp)) != 0)
+		return (err);
+
+	/* If an exec call succeeds, it never returns */
+	err = __systemcall(rval, SYS_execve + 1024, fname, argp, envp);
+	s10_assert(err != 0);
+	return (err);
+}
+
+/*
+ * S10's issetugid() syscall is now a subcode to privsys().
+ */
+static int
+s10_issetugid(sysret_t *rval)
+{
+	return (__systemcall(rval, SYS_privsys + 1024, PRIVSYS_ISSETUGID,
+	    0, 0, 0, 0, 0));
+}
+
+/*
+ * New last arg "block" flag should be zero.  The block flag is used by
+ * the Opensolaris AIO implementation, which is now part of libc.
+ */
+static int
+s10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code)
+{
+	return (__systemcall(rval, SYS_sigqueue + 1024, pid, signo, value,
+	    si_code, 0));
+}
+
+static long
+s10_uname(sysret_t *rv, uintptr_t p1)
+{
+	struct utsname un, *unp = (struct utsname *)p1;
+	int rev, err;
+
+	if ((err = __systemcall(rv, SYS_uname + 1024, &un)) != 0)
+		return (err);
+
+	rev = atoi(&un.release[2]);
+	s10_assert(rev >= 11);
+	bzero(un.release, _SYS_NMLN);
+	(void) strlcpy(un.release, S10_UTS_RELEASE, _SYS_NMLN);
+	bzero(un.version, _SYS_NMLN);
+	(void) strlcpy(un.version, S10_UTS_VERSION, _SYS_NMLN);
+
+	/* copy out the modified uname info */
+	return (s10_uucopy(&un, unp, sizeof (un)));
+}
+
+int
+s10_sysinfo(sysret_t *rv, int command, char *buf, long count)
+{
+	char *value;
+	int len;
+
+	/*
+	 * We must interpose on the sysinfo(2) commands SI_RELEASE and
+	 * SI_VERSION; all others get passed to the native sysinfo(2)
+	 * command.
+	 */
+	switch (command) {
+		case SI_RELEASE:
+			value = S10_UTS_RELEASE;
+			break;
+
+		case SI_VERSION:
+			value = S10_UTS_VERSION;
+			break;
+
+		default:
+			/*
+			 * The default action is to pass the command to the
+			 * native sysinfo(2) syscall.
+			 */
+			return (__systemcall(rv, SYS_systeminfo + 1024,
+			    command, buf, count));
+	}
+
+	len = strlen(value) + 1;
+	if (count > 0) {
+		if (s10_uucopystr(value, buf, count) != 0)
+			return (EFAULT);
+
+		/* Assure NULL termination of buf as s10_uucopystr() doesn't. */
+		if (len > count && s10_uucopy("\0", buf + (count - 1), 1) != 0)
+			return (EFAULT);
+	}
+
+	/*
+	 * On success, sysinfo(2) returns the size of buffer required to hold
+	 * the complete value plus its terminating NULL byte.
+	 */
+	(void) S10_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count);
+	rv->sys_rval1 = len;
+	rv->sys_rval2 = 0;
+	return (0);
+}
+
+#ifdef	__x86
+#ifdef	__amd64
+/*
+ * 64-bit x86 LWPs created by SYS_lwp_create start here if they need to set
+ * their %fs registers to the legacy Solaris 10 selector value.
+ *
+ * This function does three things:
+ *
+ *	1.  Trap to the kernel so that it can set %fs to the legacy Solaris 10
+ *	    selector value.
+ *	2.  Read the LWP's true entry point (the entry point supplied by libc
+ *	    when SYS_lwp_create was invoked) from %r14.
+ *	3.  Eliminate this function's stack frame and pass control to the LWP's
+ *	    true entry point.
+ *
+ * See the comment above s10_lwp_create_correct_fs() (see below) for the reason
+ * why this function exists.
+ */
+/*ARGSUSED*/
+static void
+s10_lwp_create_entry_point(void *ulwp_structp)
+{
+	sysret_t rval;
+
+	/*
+	 * The new LWP's %fs register is initially zero, but libc won't
+	 * function correctly when %fs is zero.  Change the LWP's %fs register
+	 * via SYS_brand.
+	 */
+	(void) __systemcall(&rval, SYS_brand + 1024, B_S10_FSREGCORRECTION);
+
+	/*
+	 * Jump to the true entry point, which is stored in %r14.
+	 * Remove our stack frame before jumping so that
+	 * s10_lwp_create_entry_point() won't be seen in stack traces.
+	 *
+	 * NOTE: s10_lwp_create_entry_point() pushes %r12 onto its stack frame
+	 * so that it can use it as a temporary register.  We don't restore %r12
+	 * in this assembly block because we don't care about its value (and
+	 * neither does _lwp_start()).  Besides, the System V ABI AMD64
+	 * Actirecture Processor Supplement doesn't specify that %r12 should
+	 * have a special value when LWPs start, so we can ignore its value when
+	 * we jump to the true entry point.  Furthermore, %r12 is a callee-saved
+	 * register, so the true entry point should push %r12 onto its stack
+	 * before using the register.  We ignore %r14 after we read it for
+	 * similar reasons.
+	 *
+	 * NOTE: The compiler will generate a function epilogue for this
+	 * function despite the fact that the LWP will never execute it.
+	 * We could hand-code this entire function in assembly to eliminate
+	 * the epilogue, but the epilogue is only three or four instructions,
+	 * so we wouldn't save much space.  Besides, why would we want
+	 * to create yet another ugly, hard-to-maintain assembly function when
+	 * we could write most of it in C?
+	 */
+	__asm__ __volatile__(
+	    "movq %0, %%rdi\n\t"	/* pass ulwp_structp as arg1 */
+	    "movq %%rbp, %%rsp\n\t"	/* eliminate the stack frame */
+	    "popq %%rbp\n\t"
+	    "jmp *%%r14\n\t"		/* jump to the true entry point */
+	    : : "r" (ulwp_structp));
+	/*NOTREACHED*/
+}
+
+/*
+ * The S10 libc expects that %fs will be nonzero for new 64-bit x86 LWPs but the
+ * Nevada kernel clears %fs for such LWPs.  Unforunately, new LWPs do not issue
+ * SYS_lwp_private (see s10_lwp_private() below) after they are created, so
+ * we must ensure that new LWPs invoke a brand operation that sets %fs to a
+ * nonzero value immediately after their creation.
+ *
+ * The easiest way to do this is to make new LWPs start at a special function,
+ * s10_lwp_create_entry_point() (see its definition above), that invokes the
+ * brand operation that corrects %fs.  We'll store the entry points of new LWPs
+ * in their %r14 registers so that s10_lwp_create_entry_point() can find and
+ * call them after invoking the special brand operation.  %r14 is a callee-saved
+ * register; therefore, any functions invoked by s10_lwp_create_entry_point()
+ * and all functions dealing with signals (e.g., sigacthandler()) will preserve
+ * %r14 for s10_lwp_create_entry_point().
+ *
+ * The Nevada kernel can safely work with nonzero %fs values because the kernel
+ * configures per-thread %fs segment descriptors so that the legacy %fs selector
+ * value will still work.  See the comment in lwp_load() regarding %fs and
+ * %fsbase in 64-bit x86 processes.
+ *
+ * This emulation exists thanks to CRs 6467491 and 6501650.
+ */
+static int
+s10_lwp_create_correct_fs(sysret_t *rval, ucontext_t *ucp, int flags,
+    id_t *new_lwp)
+{
+	ucontext_t s10_uc;
+
+	/*
+	 * Copy the supplied ucontext_t structure to the local stack
+	 * frame and store the new LWP's entry point (the value of %rip
+	 * stored in the ucontext_t) in the new LWP's %r14 register.
+	 * Then make s10_lwp_create_entry_point() the new LWP's entry
+	 * point.
+	 */
+	if (s10_uucopy(ucp, &s10_uc, sizeof (s10_uc)) != 0)
+		return (EFAULT);
+	s10_uc.uc_mcontext.gregs[REG_R14] = s10_uc.uc_mcontext.gregs[REG_RIP];
+	s10_uc.uc_mcontext.gregs[REG_RIP] = (greg_t)s10_lwp_create_entry_point;
+
+	/*
+	 * Issue SYS_lwp_create to create the new LWP.  We pass the
+	 * modified ucontext_t to make sure that the new LWP starts at
+	 * s10_lwp_create_entry_point().
+	 */
+	return (__systemcall(rval, SYS_lwp_create + 1024, &s10_uc,
+	    flags, new_lwp));
+}
+#endif	/* __amd64 */
+
+/*
+ * This function is invoked on x86 systems when SYS_lwp_create is issued but no
+ * %fs register correction is necessary.
+ *
+ * See the comment above s10_lwp_create_correct_fs() above for more details.
+ */
+static int
+s10_lwp_create(sysret_t *rval, ucontext_t *ucp, int flags, id_t *new_lwp)
+{
+	return (__systemcall(rval, SYS_lwp_create + 1024, ucp, flags, new_lwp));
+}
+
+/*
+ * SYS_lwp_private is issued by libc_init() to set %fsbase in 64-bit x86
+ * processes.  The Nevada kernel sets %fs to zero but the S10 libc expects
+ * %fs to be nonzero.  We'll pass the issued system call to the kernel untouched
+ * and invoke a brand operation to set %fs to the legacy S10 selector value.
+ *
+ * This emulation exists thanks to CRs 6467491 and 6501650.
+ */
+static int
+s10_lwp_private(sysret_t *rval, int cmd, int which, uintptr_t base)
+{
+#ifdef	__amd64
+	int err;
+
+	/*
+	 * The current LWP's %fs register should be zero.  Determine whether the
+	 * Solaris 10 libc with which we're working functions correctly when %fs
+	 * is zero by calling thr_main() after issuing the SYS_lwp_private
+	 * syscall.  If thr_main() barfs (returns -1), then change the LWP's %fs
+	 * register via SYS_brand and patch s10_sysent_table so that issuing
+	 * SYS_lwp_create executes s10_lwp_create_correct_fs() rather than the
+	 * default s10_lwp_create().  s10_lwp_create_correct_fs() will
+	 * guarantee that new LWPs will have correct %fs values.
+	 */
+	if ((err = __systemcall(rval, SYS_lwp_private + 1024, cmd, which,
+	    base)) != 0)
+		return (err);
+	if (thr_main() == -1) {
+		/*
+		 * SYS_lwp_private is only issued by libc_init(), which is
+		 * executed when libc is first loaded by ld.so.1.  Thus we
+		 * are guaranteed to be single-threaded at this point.  Even
+		 * if we were multithreaded at this point, writing a 64-bit
+		 * value to the st_callc field of a s10_sysent_table
+		 * entry is guaranteed to be atomic on 64-bit x86 chips
+		 * as long as the field is not split across cache lines
+		 * (It shouldn't be.).  See chapter 8, section 1.1 of
+		 * "The Intel 64 and IA32 Architectures Software Developer's
+		 * Manual," Volume 3A for more details.
+		 */
+		s10_sysent_table[SYS_lwp_create].st_callc =
+		    (sysent_cb_t)s10_lwp_create_correct_fs;
+		return (__systemcall(rval, SYS_brand + 1024,
+		    B_S10_FSREGCORRECTION));
+	}
+	return (0);
+#else	/* !__amd64 */
+	return (__systemcall(rval, SYS_lwp_private + 1024, cmd, which, base));
+#endif	/* !__amd64 */
+}
+#endif	/* __x86 */
+
+/*
+ * If the emul_global_zone flag is set then emulate some aspects of the
+ * zone system call.  In particular, emulate the global zone ID on the
+ * ZONE_LOOKUP subcommand and emulate some of the global zone attributes
+ * on the ZONE_GETATTR subcommand.  If the flag is not set or we're performing
+ * some other operation, simply pass the calls through.
+ */
+int
+s10_zone(sysret_t *rval, int cmd, void *arg1, void *arg2, void *arg3,
+    void *arg4)
+{
+	char		*aval;
+	int		len;
+	zoneid_t	zid;
+	int		attr;
+	char		*buf;
+	size_t		bufsize;
+
+	/*
+	 * We only emulate the zone syscall for a subset of specific commands,
+	 * otherwise we just pass the call through.
+	 */
+	if (!emul_global_zone)
+		return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2,
+		    arg3, arg4));
+
+	switch (cmd) {
+	case ZONE_LOOKUP:
+		(void) S10_TRUSS_POINT_1(rval, SYS_zone, 0, cmd);
+		rval->sys_rval1 = GLOBAL_ZONEID;
+		rval->sys_rval2 = 0;
+		return (0);
+
+	case ZONE_GETATTR:
+		zid = (zoneid_t)(uintptr_t)arg1;
+		attr = (int)(uintptr_t)arg2;
+		buf = (char *)arg3;
+		bufsize = (size_t)arg4;
+
+		/*
+		 * If the request is for the global zone then we're emulating
+		 * that, otherwise pass this thru.
+		 */
+		if (zid != GLOBAL_ZONEID)
+			goto passthru;
+
+		switch (attr) {
+		case ZONE_ATTR_NAME:
+			aval = GLOBAL_ZONENAME;
+			break;
+
+		case ZONE_ATTR_BRAND:
+			aval = NATIVE_BRAND_NAME;
+			break;
+		default:
+			/*
+			 * We only emulate a subset of the attrs, use the
+			 * real zone id to pass thru the rest.
+			 */
+			arg1 = (void *)(uintptr_t)zoneid;
+			goto passthru;
+		}
+
+		(void) S10_TRUSS_POINT_5(rval, SYS_zone, 0, cmd, zid, attr,
+		    buf, bufsize);
+
+		len = strlen(aval) + 1;
+		if (len > bufsize)
+			return (ENAMETOOLONG);
+
+		if (buf != NULL) {
+			if (len == 1) {
+				if (s10_uucopy("\0", buf, 1) != 0)
+					return (EFAULT);
+			} else {
+				if (s10_uucopystr(aval, buf, len) != 0)
+					return (EFAULT);
+
+				/*
+				 * Assure NULL termination of "buf" as
+				 * s10_uucopystr() does NOT.
+				 */
+				if (s10_uucopy("\0", buf + (len - 1), 1) != 0)
+					return (EFAULT);
+			}
+		}
+
+		rval->sys_rval1 = len;
+		rval->sys_rval2 = 0;
+		return (0);
+
+	default:
+		break;
+	}
+
+passthru:
+	return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, arg3,
+	    arg4));
+}
+
+/*
+ * Close a libc file handle, but don't actually close the underlying
+ * file descriptor.
+ */
+static void
+s10_close_fh(FILE *file)
+{
+	int fd, fd_new;
+
+	if (file == NULL)
+		return;
+
+	if ((fd = fileno(file)) < 0)
+		return;
+
+	fd_new = dup(fd);
+	if (fd_new == -1)
+		return;
+
+	(void) fclose(file);
+	(void) dup2(fd_new, fd);
+	(void) close(fd_new);
+}
+
+/*ARGSUSED*/
+int
+s10_init(int argc, char *argv[], char *envp[])
+{
+	sysret_t		rval;
+	s10_brand_reg_t		reg;
+	s10_elf_data_t		sed;
+	auxv_t			*ap;
+	uintptr_t		*p;
+	int			i, err;
+	char			*bname;
+
+	/* Sanity check our translation table return value codes */
+	for (i = 0; i < NSYSCALL; i++) {
+		s10_sysent_table_t *est = &(s10_sysent_table[i]);
+		s10_assert(BIT_ONLYONESET(est->st_args & RV_MASK));
+	}
+
+	/*
+	 * We need to shutdown all libc stdio.  libc stdio normally goes to
+	 * file descriptors, but since we're actually part of a another
+	 * process we don't own these file descriptors and we can't make
+	 * any assumptions about their state.
+	 */
+	s10_close_fh(stdin);
+	s10_close_fh(stdout);
+	s10_close_fh(stderr);
+
+	/*
+	 * Cache the pid of the zone's init process and determine if
+	 * we're init(1m) for the zone.  Remember: we might be init
+	 * now, but as soon as we fork(2) we won't be.
+	 */
+	(void) get_initpid_info();
+
+	/* get the current zoneid */
+	err = __systemcall(&rval, SYS_zone, ZONE_LOOKUP, NULL);
+	s10_assert(err == 0);
+	zoneid = (zoneid_t)rval.sys_rval1;
+
+	/* Get the emulation version number. */
+	if ((err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid,
+	    S10_EMUL_VERSION_NUM, &emul_vers, sizeof (emul_vers))) != 0 ||
+	    emul_vers != 0) {
+		s10_abort(err, "The zone's patch level is unsupported");
+		/*NOTREACHED*/
+	}
+
+	bname = basename(argv[0]);
+
+	/*
+	 * In general we want the S10 commands that are zone-aware to continue
+	 * to behave as they normally do within a zone.  Since these commands
+	 * are zone-aware, they should continue to "do the right thing".
+	 * However, some zone-aware commands aren't going to work the way
+	 * we expect them to inside the branded zone.  In particular, the pkg
+	 * and patch commands will not properly manage all pkgs/patches
+	 * unless the commands think they are running in the global zone.  For
+	 * these commands we want to emulate the global zone.
+	 *
+	 * We don't do any emulation for pkgcond since it is typically used
+	 * in pkg/patch postinstall scripts and we want those scripts to do
+	 * the right thing inside a zone.
+	 *
+	 * One issue is the handling of hollow pkgs.  Since the pkgs are
+	 * hollow, they won't use pkgcond in their postinstall scripts.  These
+	 * pkgs typically are installing drivers so we handle that by
+	 * replacing add_drv and rem_drv in the s10_boot script.
+	 */
+	if (strcmp("pkgadd", bname) == 0 || strcmp("pkgrm", bname) == 0 ||
+	    strcmp("patchadd", bname) == 0 || strcmp("patchrm", bname) == 0)
+		emul_global_zone = B_TRUE;
+
+	/*
+	 * Register our syscall emulation table with the kernel.
+	 * Note that we don't have to do invoke (syscall_number + 1024)
+	 * until we've actually establised a syscall emulation callback
+	 * handler address, which is what we're doing with this brand
+	 * syscall.
+	 */
+	reg.sbr_version = S10_VERSION;
+	reg.sbr_handler = (caddr_t)s10_handler;
+	if ((err = __systemcall(&rval, SYS_brand, B_REGISTER, &reg)) != 0) {
+		s10_abort(err, "Failed to brand current process");
+		/*NOTREACHED*/
+	}
+
+	/* Get data about the executable we're running from the kernel. */
+	if ((err = __systemcall(&rval, SYS_brand + 1024,
+	    B_ELFDATA, (void *)&sed)) != 0) {
+		s10_abort(err,
+		    "Failed to get required brand ELF data from the kernel");
+		/*NOTREACHED*/
+	}
+
+	/*
+	 * Find the aux vector on the stack.
+	 */
+	p = (uintptr_t *)envp;
+	while (*p != NULL)
+		p++;
+
+	/*
+	 * p is now pointing at the 0 word after the environ pointers.
+	 * After that is the aux vectors.
+	 *
+	 * The aux vectors are currently pointing to the brand emulation
+	 * library and associated linker.  We're going to change them to
+	 * point to the brand executable and associated linker (or to no
+	 * linker for static binaries).  This matches the process data
+	 * stored within the kernel and visible from /proc, which was
+	 * all setup in s10_elfexec().  We do this so that when a debugger
+	 * attaches to the process it sees the process as a normal solaris
+	 * process, this brand emulation library and everything on it's
+	 * link map will not be visible, unless our librtld_db plugin
+	 * is used.  Note that this is very different from how Linux
+	 * branded processes are implemented within lx branded zones.
+	 * In that situation, the primary linkmap of the process is the
+	 * brand emulation libraries linkmap, not the Linux applications
+	 * linkmap.
+	 *
+	 * We also need to clear the AF_SUN_NOPLM flag from the AT_SUN_AUXFLAGS
+	 * aux vector.  This flag told our linker that we don't have a
+	 * primary link map.  Now that our linker is done initializing, we
+	 * want to clear this flag before we transfer control to the
+	 * applications copy of the linker, since we want that linker to have
+	 * a primary link map which will be the link map for the application
+	 * we're running.
+	 */
+	p++;
+	for (ap = (auxv_t *)p; ap->a_type != AT_NULL; ap++) {
+		switch (ap->a_type) {
+			case AT_BASE:
+				/* Hide AT_BASE if static binary */
+				if (sed.sed_base == NULL) {
+					ap->a_type = AT_IGNORE;
+					ap->a_un.a_val = NULL;
+				} else {
+					ap->a_un.a_val = sed.sed_base;
+				}
+				break;
+			case AT_ENTRY:
+				ap->a_un.a_val = sed.sed_entry;
+				break;
+			case AT_PHDR:
+				ap->a_un.a_val = sed.sed_phdr;
+				break;
+			case AT_PHENT:
+				ap->a_un.a_val = sed.sed_phent;
+				break;
+			case AT_PHNUM:
+				ap->a_un.a_val = sed.sed_phnum;
+				break;
+			case AT_SUN_AUXFLAGS:
+				ap->a_un.a_val &= ~AF_SUN_NOPLM;
+				break;
+			case AT_SUN_EMULATOR:
+				/*
+				 * ld.so.1 inspects AT_SUN_EMULATOR to see if
+				 * if it is the linker for the brand emulation
+				 * library.  Hide AT_SUN_EMULATOR, as the
+				 * linker we are about to jump to is the linker
+				 * for the binary.
+				 */
+				ap->a_type = AT_IGNORE;
+				ap->a_un.a_val = NULL;
+				break;
+			case AT_SUN_LDDATA:
+				/* Hide AT_SUN_LDDATA if static binary */
+				if (sed.sed_lddata == NULL) {
+					ap->a_type = AT_IGNORE;
+					ap->a_un.a_val = NULL;
+				} else {
+					ap->a_un.a_val = sed.sed_lddata;
+				}
+				break;
+			default:
+				break;
+		}
+	}
+
+	s10_runexe(argv, sed.sed_ldentry);
+	/*NOTREACHED*/
+	s10_abort(0, "s10_runexe() returned");
+	return (-1);
+}
+
+/*
+ * This table must have at least NSYSCALL entries in it.
+ *
+ * The second parameter of each entry in the s10_sysent_table
+ * contains the number of parameters and flags that describe the
+ * syscall return value encoding.  See the block comments at the
+ * top of this file for more information about the syscall return
+ * value flags and when they should be used.
+ */
+s10_sysent_table_t s10_sysent_table[] = {
+#if defined(__sparc) && !defined(__sparcv9)
+	EMULATE(s10_indir, 9 | RV_64RVAL),	/*  0 */
+#else /* !__sparc || __sparcv9 */
+	NOSYS,					/*  0 */
+#endif /* !__sparc || __sparcv9 */
+	NOSYS,					/*   1 */
+	NOSYS,					/*   2 */
+	NOSYS,					/*   3 */
+	NOSYS,					/*   4 */
+	NOSYS,					/*   5 */
+	NOSYS,					/*   6 */
+	NOSYS,					/*   7 */
+	NOSYS,					/*   8 */
+	NOSYS,					/*   9 */
+	NOSYS,					/*  10 */
+	EMULATE(s10_exec, 2 | RV_DEFAULT),	/*  11 */
+	NOSYS,					/*  12 */
+	NOSYS,					/*  13 */
+	NOSYS,					/*  14 */
+	NOSYS,					/*  15 */
+	NOSYS,					/*  16 */
+	NOSYS,					/*  17 */
+	NOSYS,					/*  18 */
+	NOSYS,					/*  19 */
+	NOSYS,					/*  20 */
+	NOSYS,					/*  21 */
+	NOSYS,					/*  22 */
+	NOSYS,					/*  23 */
+	NOSYS,					/*  24 */
+	NOSYS,					/*  25 */
+	NOSYS,					/*  26 */
+	NOSYS,					/*  27 */
+	NOSYS,					/*  28 */
+	NOSYS,					/*  29 */
+	NOSYS,					/*  30 */
+	NOSYS,					/*  31 */
+	NOSYS,					/*  32 */
+	NOSYS,					/*  33 */
+	NOSYS,					/*  34 */
+	NOSYS,					/*  35 */
+	NOSYS,					/*  36 */
+	NOSYS,					/*  37 */
+	NOSYS,					/*  38 */
+	NOSYS,					/*  39 */
+	NOSYS,					/*  40 */
+	NOSYS,					/*  41 */
+	NOSYS,					/*  42 */
+	NOSYS,					/*  43 */
+	NOSYS,					/*  44 */
+	NOSYS,					/*  45 */
+	NOSYS,					/*  46 */
+	NOSYS,					/*  47 */
+	NOSYS,					/*  48 */
+	NOSYS,					/*  49 */
+	NOSYS,					/*  50 */
+	NOSYS,					/*  51 */
+	NOSYS,					/*  52 */
+	NOSYS,					/*  53 */
+	EMULATE(s10_ioctl, 3 | RV_DEFAULT),	/*  54 */
+	NOSYS,					/*  55 */
+	NOSYS,					/*  56 */
+	NOSYS,					/*  57 */
+	NOSYS,					/*  58 */
+	EMULATE(s10_execve, 3 | RV_DEFAULT),	/*  59 */
+	NOSYS,					/*  60 */
+	NOSYS,					/*  61 */
+	NOSYS,					/*  62 */
+	NOSYS,					/*  63 */
+	NOSYS,					/*  64 */
+	NOSYS,					/*  65 */
+	NOSYS,					/*  66 */
+	NOSYS,					/*  67 */
+	NOSYS,					/*  68 */
+	NOSYS,					/*  69 */
+	NOSYS,					/*  70 */
+	EMULATE(s10_acctctl, 3 | RV_DEFAULT),	/*  71 */
+	NOSYS,					/*  72 */
+	NOSYS,					/*  73 */
+	NOSYS,					/*  74 */
+	EMULATE(s10_issetugid, 0 | RV_DEFAULT),	/*  75 */
+	NOSYS,					/*  76 */
+	NOSYS,					/*  77 */
+	NOSYS,					/*  78 */
+	NOSYS,					/*  79 */
+	NOSYS,					/*  80 */
+	NOSYS,					/*  81 */
+	NOSYS,					/*  82 */
+	NOSYS,					/*  83 */
+	NOSYS,					/*  84 */
+	NOSYS,					/*  85 */
+	NOSYS,					/*  86 */
+	NOSYS,					/*  87 */
+	NOSYS,					/*  88 */
+	NOSYS,					/*  89 */
+	NOSYS,					/*  90 */
+	NOSYS,					/*  91 */
+	NOSYS,					/*  92 */
+	NOSYS,					/*  93 */
+	NOSYS,					/*  94 */
+	NOSYS,					/*  95 */
+	NOSYS,					/*  96 */
+	NOSYS,					/*  97 */
+	NOSYS,					/*  98 */
+	NOSYS,					/*  99 */
+	NOSYS,					/* 100 */
+	NOSYS,					/* 101 */
+	NOSYS,					/* 102 */
+	NOSYS,					/* 103 */
+	NOSYS,					/* 104 */
+	NOSYS,					/* 105 */
+	NOSYS,					/* 106 */
+	NOSYS,					/* 107 */
+	NOSYS,					/* 108 */
+	NOSYS,					/* 109 */
+	NOSYS,					/* 110 */
+	NOSYS,					/* 111 */
+	NOSYS,					/* 112 */
+	NOSYS,					/* 113 */
+	NOSYS,					/* 114 */
+	NOSYS,					/* 115 */
+	NOSYS,					/* 116 */
+	NOSYS,					/* 117 */
+	NOSYS,					/* 118 */
+	NOSYS,					/* 119 */
+	NOSYS,					/* 120 */
+	NOSYS,					/* 121 */
+	NOSYS,					/* 122 */
+	NOSYS,					/* 123 */
+	NOSYS,					/* 124 */
+	NOSYS,					/* 125 */
+	NOSYS,					/* 126 */
+	NOSYS,					/* 127 */
+	NOSYS,					/* 128 */
+	NOSYS,					/* 129 */
+	NOSYS,					/* 130 */
+	NOSYS,					/* 131 */
+	NOSYS,					/* 132 */
+	NOSYS,					/* 133 */
+	NOSYS,					/* 134 */
+	EMULATE(s10_uname, 1 | RV_DEFAULT),	/* 135 */
+	NOSYS,					/* 136 */
+	NOSYS,					/* 137 */
+	NOSYS,					/* 138 */
+	EMULATE(s10_sysinfo, 3 | RV_DEFAULT),	/* 139 */
+	NOSYS,					/* 140 */
+	NOSYS,					/* 141 */
+	NOSYS,					/* 142 */
+	NOSYS,					/* 143 */
+	NOSYS,					/* 144 */
+	NOSYS,					/* 145 */
+	NOSYS,					/* 146 */
+	NOSYS,					/* 147 */
+	NOSYS,					/* 148 */
+	NOSYS,					/* 149 */
+	NOSYS,					/* 150 */
+	NOSYS,					/* 151 */
+	NOSYS,					/* 152 */
+	NOSYS,					/* 153 */
+	NOSYS,					/* 154 */
+	NOSYS,					/* 155 */
+	NOSYS,					/* 156 */
+	NOSYS,					/* 157 */
+	NOSYS,					/* 158 */
+#ifdef	__x86
+	EMULATE(s10_lwp_create, 3 | RV_DEFAULT), /* 159 */
+#else	/* !__x86 */
+	NOSYS,					/* 159 */
+#endif	/* !__x86 */
+	NOSYS,					/* 160 */
+	NOSYS,					/* 161 */
+	NOSYS,					/* 162 */
+	NOSYS,					/* 163 */
+	NOSYS,					/* 164 */
+	NOSYS,					/* 165 */
+#ifdef	__x86
+	EMULATE(s10_lwp_private, 3 | RV_DEFAULT), /* 166 */
+#else	/* !__x86 */
+	NOSYS,					/* 166 */
+#endif	/* !__x86 */
+	NOSYS,					/* 167 */
+	NOSYS,					/* 168 */
+	NOSYS,					/* 169 */
+	NOSYS,					/* 170 */
+	NOSYS,					/* 171 */
+	NOSYS,					/* 172 */
+	NOSYS,					/* 173 */
+	EMULATE(s10_pwrite, 4 | RV_DEFAULT),	/* 174 */
+	NOSYS,					/* 175 */
+	NOSYS,					/* 176 */
+	NOSYS,					/* 177 */
+	NOSYS,					/* 178 */
+	NOSYS,					/* 179 */
+	NOSYS,					/* 180 */
+	NOSYS,					/* 181 */
+	NOSYS,					/* 182 */
+	NOSYS,					/* 183 */
+	NOSYS,					/* 184 */
+	NOSYS,					/* 185 */
+	EMULATE(s10_auditsys, 4 | RV_64RVAL),	/* 186 */
+	NOSYS,					/* 187 */
+	NOSYS,					/* 188 */
+	NOSYS,					/* 189 */
+	EMULATE(s10_sigqueue, 4 | RV_DEFAULT),	/* 190 */
+	NOSYS,					/* 191 */
+	NOSYS,					/* 192 */
+	NOSYS,					/* 193 */
+	NOSYS,					/* 194 */
+	NOSYS,					/* 195 */
+	NOSYS,					/* 196 */
+	NOSYS,					/* 197 */
+	NOSYS,					/* 198 */
+	NOSYS,					/* 199 */
+	NOSYS,					/* 200 */
+	NOSYS,					/* 201 */
+	NOSYS,					/* 202 */
+	NOSYS,					/* 203 */
+	NOSYS,					/* 204 */
+	NOSYS,					/* 205 */
+	NOSYS,					/* 206 */
+	NOSYS,					/* 207 */
+	NOSYS,					/* 208 */
+	NOSYS,					/* 209 */
+	NOSYS,					/* 210 */
+	NOSYS,					/* 211 */
+	NOSYS,					/* 212 */
+	NOSYS,					/* 213 */
+	NOSYS,					/* 214 */
+	NOSYS,					/* 215 */
+	NOSYS,					/* 216 */
+	NOSYS,					/* 217 */
+	NOSYS,					/* 218 */
+	NOSYS,					/* 219 */
+	NOSYS,					/* 220 */
+	NOSYS,					/* 221 */
+	NOSYS,					/* 222 */
+#ifdef	_LP64
+	NOSYS,					/* 223 */
+#else	/* !_LP64 */
+	EMULATE(s10_pwrite64, 5 | RV_DEFAULT),	/* 223 */
+#endif	/* !_LP64 */
+	NOSYS,					/* 224 */
+	NOSYS,					/* 225 */
+	NOSYS,					/* 226 */
+	EMULATE(s10_zone, 5 | RV_DEFAULT),	/* 227 */
+	NOSYS,					/* 228 */
+	NOSYS,					/* 229 */
+	NOSYS,					/* 230 */
+	NOSYS,					/* 231 */
+	NOSYS,					/* 232 */
+	NOSYS,					/* 233 */
+	NOSYS,					/* 234 */
+	NOSYS,					/* 235 */
+	NOSYS,					/* 236 */
+	NOSYS,					/* 237 */
+	NOSYS,					/* 238 */
+	NOSYS,					/* 239 */
+	NOSYS,					/* 240 */
+	NOSYS,					/* 241 */
+	NOSYS,					/* 242 */
+	NOSYS,					/* 243 */
+	NOSYS,					/* 244 */
+	NOSYS,					/* 245 */
+	NOSYS,					/* 246 */
+	NOSYS,					/* 247 */
+	NOSYS,					/* 248 */
+	NOSYS,					/* 249 */
+	NOSYS,					/* 250 */
+	NOSYS,					/* 251 */
+	NOSYS,					/* 252 */
+	NOSYS,					/* 253 */
+	NOSYS,					/* 254 */
+	NOSYS					/* 255 */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/i386/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+ISASRCDIR =		.
+
+include ../Makefile.com
+
+#
+# see ../Makefile.com for why we explicity make ld.so.1 our interpreter
+#
+# S10 linker
+DYNFLAGS +=		-Wl,-I/lib/ld.so.1
+
+CLEANFILES +=		$(DYNLIB)
+CLOBBERFILES +=		$(ROOTLIBS)
+
+install: all $(ROOTLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_crt.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+
+#if defined(lint)
+
+void
+_start(void)
+{
+}
+
+#else	/* lint */
+	/*
+	 * Initial entry point for the brand emulation library.
+	 *
+	 * This platform specific assembly entry point exists just to invoke
+	 * the common brand library startup routine.  That routine expects to
+	 * be called with the following arguments:
+	 *	s10_init(int argc, char *argv[], char *envp[])
+	 *
+	 * There are no arguments explicitly passed to this entry point,
+	 * routine, but we do know how our initial stack has been setup by
+	 * the kernel.  The stack format is documented in:
+	 *	usr/src/cmd/sgs/rtld/i386/boot.s
+	 *
+	 * So this routine will troll through the stack to setup the argument
+	 * values for the common brand library startup routine and then invoke
+	 * it.  This routine is modeled after the default crt1.s`_start()
+	 * routines.
+	 */
+	ENTRY_NP(_start)
+
+	/* Make stack traces look pretty, build a fake stack frame. */
+	pushl	$0			/ retpc = NULL
+	pushl	$0			/ fp = NULL
+	movl	%esp, %ebp		/ first stack frame
+
+	/*
+	 * Calculate the location of the envp array by adding the size of
+	 * the argv array to the start of the argv array.
+	 */
+	movl	8(%ebp), %eax		/ argc in %eax
+	leal	12(%ebp), %ebx		/ &argv[0] in %ebx
+	leal	16(%ebp,%eax,4), %ecx	/ envp in %ecx
+
+	pushl	%ecx			/ push envp (3rd param)
+	pushl	%ebx			/ push argv (2nd param)
+	pushl	%eax			/ push argc (1st param)
+	call	s10_init
+
+	/*NOTREACHED*/
+	SET_SIZE(_start)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_handler.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,159 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <s10_misc.h>
+
+#if defined(lint)
+
+void
+s10_handler(void)
+{
+}
+
+#else	/* lint */
+
+#define	PIC_SETUP(r)					\
+	call	9f;					\
+9:							\
+	popl	r;					\
+	addl	$_GLOBAL_OFFSET_TABLE_ + [. - 9b], r
+
+	/*
+	 * %eax - syscall number
+	 * stack contains:
+	 *         --------------------------------------
+	 *    |  8 | syscall arguments			|
+	 *    v  4 | syscall wrapper return address	|
+	 *  %esp+0 | syscall return address		|
+	 *         --------------------------------------
+	 */
+	ENTRY_NP(s10_handler)
+	pushl	%ebp				/* allocate a stack frame */
+	movl	%esp, %ebp
+
+	/* Save registers at the time of the syscall. */
+	movl	$0, EH_LOCALS_GREG(TRAPNO)(%ebp)
+	movl	$0, EH_LOCALS_GREG(ERR)(%ebp)
+	movl	%eax, EH_LOCALS_GREG(EAX)(%ebp)
+	movl	%ebx, EH_LOCALS_GREG(EBX)(%ebp)
+	movl	%ecx, EH_LOCALS_GREG(ECX)(%ebp)
+	movl	%edx, EH_LOCALS_GREG(EDX)(%ebp)
+	movl	%edi, EH_LOCALS_GREG(EDI)(%ebp)
+	movl	%esi, EH_LOCALS_GREG(ESI)(%ebp)
+	mov	%cs, EH_LOCALS_GREG(CS)(%ebp)
+	mov	%ds, EH_LOCALS_GREG(DS)(%ebp)
+	mov	%es, EH_LOCALS_GREG(ES)(%ebp)
+	mov	%fs, EH_LOCALS_GREG(FS)(%ebp)
+	mov	%gs, EH_LOCALS_GREG(GS)(%ebp)
+	pushfl					/* save syscall flags */
+	popl	%ecx
+	movl	%ecx, EH_LOCALS_GREG(EFL)(%ebp)
+	movl	EH_ARGS_OFFSET(0)(%ebp), %ecx	/* save syscall ebp */
+	movl	%ecx, EH_LOCALS_GREG(EBP)(%ebp)
+	movl	%ebp, %ecx			/* save syscall esp */
+	addl	$CPTRSIZE, %ecx
+	movl	%ecx, EH_LOCALS_GREG(ESP)(%ebp)
+	movl	EH_ARGS_OFFSET(1)(%ebp), %ecx	/* save syscall ret address */
+	movl	%ecx, EH_LOCALS_GREG(EIP)(%ebp)
+
+	/*
+	 * Finish setting up our stack frame.  We would normally do this
+	 * upon entry to this function, but in this case we delayed it
+	 * because a "sub" operation can modify flags and we wanted to
+	 * save the flags into the gregset_t above before they get modified.
+	 *
+	 * Our stack frame format is documented in s10_misc.h.
+	 */
+	subl	$EH_LOCALS_SIZE, %esp
+
+	/* Look up the system call's entry in the sysent table */
+	PIC_SETUP(%ecx)
+	movl	s10_sysent_table@GOT(%ecx), %edx   /* %edx = sysent_table */
+	shll	$3, %eax	/* each entry is 8 bytes */
+	add	%eax, %edx	/* %edx = sysent entry address */
+
+	/*
+	 * Get the return value flag and the number of arguments from the
+	 * sysent table.
+	 */
+	movl	CPTRSIZE(%edx), %ecx		/* number of args + rv flag */
+	andl	$RV_MASK, %ecx			/* strip out number of args */
+	movl	%ecx, EH_LOCALS_RVFLAG(%ebp)	/* save rv flag */
+	movl	CPTRSIZE(%edx), %ecx		/* number of args + rv flag */
+	andl	$NARGS_MASK, %ecx		/* strip out rv flag */
+
+	/*
+	 * Setup arguments for our emulation call.  Our input arguments,
+	 * 0 to N, will become emulation call arguments 1 to N+1.
+	 * %ecx == number of arguments.
+	 */
+	movl	%ebp, %esi			/* args are at 12(%ebp) */
+	addl	$EH_ARGS_OFFSET(3), %esi	
+	movl	%esp, %edi			/* copy args to 4(%esp) */
+	addl	$EH_ARGS_OFFSET(1), %edi	
+	rep;	smovl				/* copy: (%esi) -> (%edi) */
+						/* copy: %ecx 32-bit words */
+	movl	EH_LOCALS_GREG(ESI)(%ebp), %esi	/* restore %esi */
+	movl	EH_LOCALS_GREG(EDI)(%ebp), %edi	/* restore %edi */
+
+	/*
+	 * The first parameter to the emulation callback function is a
+	 * pointer to a sysret_t structure.
+	 */
+	movl	%ebp, %ecx
+	addl	$EH_LOCALS_SYSRET, %ecx
+	movl	%ecx, EH_ARGS_OFFSET(0)(%esp)	/* arg0 == sysret_t ptr */
+
+	/* invoke the emulation routine */
+	ALTENTRY(s10_handler_savepc)
+	call	*(%edx)				/* call emulation routine */
+
+	/* restore scratch registers */
+	movl	EH_LOCALS_GREG(ECX)(%ebp), %ecx	/* restore %ecx */
+	movl	EH_LOCALS_GREG(EDX)(%ebp), %edx	/* restore %edx */
+
+	/* Check for syscall emulation success or failure */
+	cmpl	$0, %eax			/* check for an error */
+	je	success
+	stc					/* failure, set carry flag */
+	jmp	return				/* return, %rax == errno */
+
+success:
+	/* There is always at least one return value. */
+	movl	EH_LOCALS_SYSRET1(%ebp), %eax	/* %eax == sys_rval1 */
+	cmpl	$RV_DEFAULT, EH_LOCALS_RVFLAG(%ebp) /* check rv flag */
+	je	clear_carry
+	mov	EH_LOCALS_SYSRET2(%ebp), %edx	/* %edx == sys_rval2 */
+clear_carry:
+	clc					/* success, clear carry flag */
+
+return:
+	movl	%ebp, %esp			/* restore stack */
+	popl	%ebp
+	ret					/* ret to instr after syscall */
+	SET_SIZE(s10_handler)
+
+
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_runexe.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <s10_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+s10_runexe(void *argv, ulong_t entry)
+{
+}
+
+#else	/* lint */
+	/*
+	 * Prepare to jump to the target program we actually want to run.
+	 * If this program is dynamically linked then we'll be jumping to
+	 * another copy of the linker.  If it's a statically linked program
+	 * we'll be jumping directy to it's main entry point.  In any case,
+	 * we need to reset our current state stack and register state to
+	 * something similar to the initial process state setup by the kernel
+	 * and documented at:
+	 *	usr/src/cmd/sgs/rtld/i386/boot.s
+	 *	usr/src/cmd/sgs/rtld/sparcv9/boot.s
+	 *
+	 * Of course this is the same stack format as when this executable
+	 * was first started, so here we'll just roll back the stack and
+	 * frame pointers to their values when this processes first started
+	 * execution.
+	 */
+	ENTRY_NP(s10_runexe)
+
+	movl	4(%esp), %eax		/ %eax = &argv[0]
+	movl	8(%esp), %ebx		/ Brand app entry point in %ebx
+	subl	$4, %eax		/ Top of stack - must point at argc
+	movl	%eax, %esp		/ Set %esp to what linkers expect
+
+	/*
+	 * We also have to make sure to clear %edx since nornally ld.so.1 will
+	 * set that to non-zero if there is an exit function that should be
+	 * invoked when the process is terminating.  This isn't actually
+	 * necessary if the target program we're jumping to is a dynamically
+	 * linked program since in that case we're actually jumping to another
+	 * copy of ld.so.1 and it will just reset %edx, but if the target
+	 * program we're jumping to is a statically linked binary that uses
+	 * the standard sun compiler supplied crt1.o`_start(), it will check
+	 * to see if %g1 is set.
+	 */
+	movl	$0, %edx
+
+	jmp	*%ebx			/ And away we go...
+	/*
+	 * target will never return.
+	 */
+	SET_SIZE(s10_runexe)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,40 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+ISASRCDIR =		.
+
+include ../Makefile.com
+
+#
+# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter
+#
+# S10 linker
+DYNFLAGS +=		-Wl,-I/lib/ld.so.1
+ASFLAGS +=		-xarch=v8plus ${AS_PICFLAGS}
+
+CLEANFILES +=		$(DYNLIB)
+CLOBBERFILES +=		$(ROOTLIBS)
+
+install: all $(ROOTLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_crt.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <sys/link.h>
+
+#if defined(lint)
+
+void
+_start(void)
+{
+}
+
+#else	/* lint */
+	.section	".text"
+	/*
+	 * Initial entry point for the brand emulation library.
+	 *
+	 * This platform specific assembly entry point exists just to invoke
+	 * the common brand library startup routine.  That routine expects to
+	 * be called with the following arguments:
+	 *	s10_init(int argc, char *argv[], char *envp[])
+	 *
+	 * There are no arguments explicitly passed to this entry point,
+	 * routine, but we do know how our initial stack has been setup by
+	 * the kernel.  The stack format is documented in:
+	 *	usr/src/cmd/sgs/rtld/sparc/boot.s
+	 *	usr/src/cmd/sgs/rtld/sparcv9/boot.s
+	 *
+	 * So this routine will troll through the stack to setup the argument
+	 * values for the common brand library startup routine and then invoke
+	 * it.
+	 */
+	ENTRY_NP(_start)
+#if defined (__sparcv9)
+	save	%sp, -SA(MINFRAME + EB_MAX_SIZE64), %sp
+#else /* !__sparcv9 */
+	save	%sp, -SA(MINFRAME + EB_MAX_SIZE32), %sp
+#endif /* !__sparcv9 */
+
+	/* get argc */
+	ldn	[%fp + WINDOWSIZE + STACK_BIAS], %o0
+
+	/* get argv */
+	add	%fp, + WINDOWSIZE + CPTRSIZE + STACK_BIAS, %o1
+
+	/* get envp */
+	add	%o0, 1, %l0		! add 1 to argc for last element of 0
+	sll	%l0, CPTRSHIFT, %l0	! multiply argc by pointer size
+	add	%o1, %l0, %o2		!  and add to argv to get first env ptr
+
+	call	s10_init
+	nop
+
+	/*NOTREACHED*/
+	SET_SIZE(_start)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_handler.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,225 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <s10_misc.h>
+
+#if defined(lint)
+
+void
+s10_handler(void)
+{
+}
+
+#else	/* !lint */
+
+#define	PIC_SETUP(r)						\
+	mov	%o7, %g1;					\
+9:	call	8f;						\
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), r;	\
+8:	or	r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), r;	\
+	add	r, %o7, r;					\
+	mov	%g1, %o7
+
+/*
+ * Translate a global symbol into an address.  The resulting address
+ * is returned in the first register parameter.  The second register
+ * is just for scratch space.
+ */
+#if defined(__sparcv9)
+#define	GET_SYM_ADDR(r1, r2, name)		\
+	PIC_SETUP(r1)				;\
+	sethi	%hi(name), r2			;\
+	or	r2, %lo(name), r2		;\
+	ldn	[r2 + r1], r1
+#else /* !__sparcv9 */
+#define	GET_SYM_ADDR(r1, r2, name)		\
+	PIC_SETUP(r1);			\
+	ld	[r1 + name], r1
+#endif /* !__sparcv9 */
+
+	.section	".text"
+
+	/*
+	 * When we get here, %g1 should contain the system call and
+	 * %g5 should contain the address immediately after the trap
+	 * instruction.
+	 */
+	ENTRY_NP(s10_handler)
+
+	/*
+	 * 64-bit sparc may need to save 3 parameters on the stack.
+	 * 32-bit sparc may need to save 4 parameters on the stack.
+	 *
+	 * Our stack frame format is documented in s10_misc.h.
+	 */
+	save	%sp, -SA(MINFRAME + EH_LOCALS_SIZE), %sp
+
+	/*
+	 * Save the current caller state into gregs and gwins.
+	 * Note that this state isn't exact, %g1 and %g5 have been
+	 * already been lost.  Also, we've pushed a stack frame so
+	 * the callers output registers are our input registers.
+	 */
+	stn	%g0, [%sp + EH_LOCALS_GREG(REG_G1)]	/* %g1 is lost */
+	stn	%g2, [%sp + EH_LOCALS_GREG(REG_G2)]
+	stn	%g3, [%sp + EH_LOCALS_GREG(REG_G3)]
+	stn	%g4, [%sp + EH_LOCALS_GREG(REG_G4)]
+	stn	%g0, [%sp + EH_LOCALS_GREG(REG_G5)]	/* %g5 is lost */
+	stn	%g6, [%sp + EH_LOCALS_GREG(REG_G6)]
+	stn	%g7, [%sp + EH_LOCALS_GREG(REG_G7)]
+	stn	%i0, [%sp + EH_LOCALS_GREG(REG_O0)]
+	stn	%i1, [%sp + EH_LOCALS_GREG(REG_O1)]
+	stn	%i2, [%sp + EH_LOCALS_GREG(REG_O2)]
+	stn	%i3, [%sp + EH_LOCALS_GREG(REG_O3)]
+	stn	%i4, [%sp + EH_LOCALS_GREG(REG_O4)]
+	stn	%i5, [%sp + EH_LOCALS_GREG(REG_O5)]
+	stn	%i6, [%sp + EH_LOCALS_GREG(REG_O6)]
+	stn	%i7, [%sp + EH_LOCALS_GREG(REG_O7)]
+	sub	%g5, 4, %o0
+	stn	%o0, [%sp + EH_LOCALS_GREG(REG_PC)]
+	stn	%g5, [%sp + EH_LOCALS_GREG(REG_nPC)]
+	rd	%y, %o0
+	stn	%o0, [%sp + EH_LOCALS_GREG(REG_Y)]
+#if defined(__sparcv9)
+	stn	%g0, [%sp + EH_LOCALS_GREG(REG_ASI)]
+	rd	%fprs, %o0
+	stn	%o0, [%sp + EH_LOCALS_GREG(REG_FPRS)]
+#endif /* __sparcv9 */
+
+	/*
+	 * Look up the system call's entry in the sysent table
+	 * and obtain the address of the proper emulation routine (%l2).
+	 */
+	mov	%g1, %l5			/* save syscall number */
+	GET_SYM_ADDR(%l1, %l2, s10_sysent_table)
+	mov	%l5, %g1			/* restore syscall number */
+	sll	%g1, (1 + CLONGSHIFT), %l2	/* Each entry has 2 longs */
+	add	%l2, %l1, %l2			/* index to proper entry */
+	ldn	[%l2], %l2			/* emulation func address */
+
+	/*
+	 * Look up the system call's entry in the sysent table,
+	 * taking into account the posibility of indirect system calls, and
+	 * obtain the number of arguments (%l4) and return value flag (%l3).
+	 */
+#if defined(__sparcv9)
+	mov	%g1, %l3			/* %g1 == syscall number */
+#else /* !__sparcv9 */
+	/*
+	 * Check for indirect system calls, in which case the real syscall
+	 * number is the first parameter to the indirect system call.
+	 */
+	cmp	%g1, %g0			/* saved syscall number */
+	bne,a,pt %icc, no_indir			/* indirect syscall? */
+	mov	%g1, %l3			/* %g1 == syscall number */
+	mov	%i0, %l3			/* %i0 == syscall number */
+no_indir:
+#endif /* !__sparcv9 */
+	sll	%l3, (1 + CLONGSHIFT), %l3	/* Each entry has 2 longs */
+	add	%l3, %l1, %l3			/* index to proper entry */
+	ldn	[%l3 + CPTRSIZE], %l4		/* number of args + rv flag */
+	sethi	%hi(RV_MASK), %l5
+	or	%l5, %lo(RV_MASK), %l5
+	andcc	%l4, %l5, %l3			/* strip out number of args*/
+	andcc	%l4, NARGS_MASK, %l4		/* strip out rv flag */
+
+	/*
+	 * Setup arguments for our emulation call.  Our input arguments,
+	 * 0 to N, will become emulation call arguments 1 to N+1.
+	 * %l4 == number of arguments.
+	 */
+	mov	%i0, %o1
+	mov	%i1, %o2
+	mov	%i2, %o3
+	mov	%i3, %o4
+	mov	%i4, %o5
+
+	/* 7th argument and above get passed on the stack */
+	cmp	%l4, 0x6
+	bl,pt	%ncc, args_copied
+	nop
+	stn	%i5, [%sp + EH_ARGS_OFFSET(0)]	/* copy 6th syscall arg */
+	cmp	%l4, 0x7
+	bl,pt	%ncc, args_copied
+	nop
+	ldn	[%fp + EH_ARGS_OFFSET(0)], %l5	/* copy 7th syscall arg */
+	stn	%l5, [%sp + EH_ARGS_OFFSET(1)]
+	cmp	%l4, 0x8
+	bl,pt	%ncc, args_copied
+	nop
+	ldn	[%fp + EH_ARGS_OFFSET(1)], %l5
+	stn	%l5, [%sp + EH_ARGS_OFFSET(2)]	/* copy 8th syscall arg */
+#if !defined(__sparcv9)
+	cmp	%l4, 0x9
+	bl,pt	%ncc, args_copied
+	nop
+	ldn	[%fp + EH_ARGS_OFFSET(2)], %l5
+	stn	%l5, [%sp + EH_ARGS_OFFSET(3)]	/* copy 9th syscall arg */
+#endif /* !__sparcv9 */
+
+args_copied:
+	/*
+	 * The first parameter to the emulation callback function is a
+	 * pointer to a sysret_t structure.
+	 *
+	 * invoke the emulation routine.
+	 */
+	ALTENTRY(s10_handler_savepc)
+	call	%l2
+	add	%sp, EH_LOCALS_SYSRET, %o0	/* arg0 == sysret_t ptr */
+
+	/* Check for syscall emulation success or failure */
+	cmp	%g0, %o0
+	be	success
+	nop
+	subcc   %g0, 1, %g0			/* failure, set carry flag */
+	ba	return
+	mov	%o0, %i0			/* return, %o0 == errno */
+
+success:
+	/* There is always at least one return value. */
+	ldn	[%sp + EH_LOCALS_SYSRET1], %i0	/* %i0 == sys_rval1 */
+	cmp	%l3, RV_DEFAULT			/* check rv flag */
+	be,a	clear_carry
+	mov	%g0, %i1			/* clear second rval */
+	ldn	[%sp + EH_LOCALS_SYSRET2], %i1	/* %i1 == sys_rval2 */
+clear_carry:
+	addcc	%g0, %g0, %g0			/* success, clear carry flag */
+
+return:
+	/*
+	 * Our syscall emulation is complete.  Return to the caller that
+	 * originally invoked a system which needed emulation.  Note that
+	 * we have to load the return address that we saved earlier because
+	 * it's possible that %g5 was overwritten by a nested call into
+	 * this emulation library.
+	 */
+	ldn	[%sp + EH_LOCALS_GREG(REG_nPC)], %g5
+	jmp	%g5
+	restore					/* delay slot */
+	SET_SIZE(s10_handler)
+
+
+#endif	/* !lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_runexe.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,82 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <s10_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+s10_runexe(void *argv, ulong_t entry)
+{
+}
+
+#else	/* lint */
+	.section	".text"
+	ENTRY_NP(s10_runexe)
+	/*
+	 * Prepare to jump to the target program we actually want to run.
+	 * If this program is dynamically linked then we'll be jumping to
+	 * another copy of the linker.  If it's a statically linked program
+	 * we'll be jumping directy to it's main entry point.  In any case,
+	 * we need to reset our current state stack and register state to
+	 * something similar to the initial process state setup by the kernel
+	 * and documented at:
+	 *	usr/src/cmd/sgs/rtld/sparc/boot.s
+	 *	usr/src/cmd/sgs/rtld/sparcv9/boot.s
+	 *
+	 * Of course this is the same stack format as when this executable
+	 * was first started, so here we'll just roll back the stack and
+	 * frame pointers to their values when this processes first started
+	 * execution.
+	 *
+	 * Our input parameters are stored in the %o? registers since we
+	 * don't bother to allocate a new stack frame.
+	 */
+	sub	%o0, CPTRSIZE + WINDOWSIZE + STACK_BIAS, %sp
+	clr	%fp
+
+	/*
+	 * We also have to make sure to clear %g1 since nornally ld.so.1 will
+	 * set that to non-zero if there is an exit function that should be
+	 * invoked when the process is terminating.  This isn't actually
+	 * necessary if the target program we're jumping to is a dynamically
+	 * linked program since in that case we're actually jumping to another
+	 * copy of ld.so.1 and it will just reset %g1, but if the target
+	 * program we're jumping to is a statically linked binary that uses
+	 * the standard sun compiler supplied crt1.o`_start(), it will check
+	 * to see if %g1 is set.
+	 */
+	clr	%g1
+
+	jmp	%o1	! jump to the target processes entry point
+	nop
+	/*
+	 * target will never return.
+	 */
+	SET_SIZE(s10_runexe)
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sparcv9/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+ISASRCDIR =		../sparc
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+#
+# see ../Makefile.com for why we explicity make ld.so.1 our interpreter
+#
+# S10 linker
+DYNFLAGS +=		-Wl,-I/lib/64/ld.so.1
+ASFLAGS_$(CURTYPE) +=	${AS_PICFLAGS}
+
+CLEANFILES +=		$(DYNLIB)
+CLOBBERFILES +=		$(ROOTLIBS64)
+
+install: all $(ROOTLIBS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,199 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _S10_MISC_H
+#define	_S10_MISC_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * This header file must uses _ASM defines to allow it to be included
+ * in assmebly source files
+ */
+#include <sys/asm_linkage.h>
+#include <sys/regset.h>
+#include <sys/syscall.h>
+#include "assym.h"
+
+/*
+ * Our syscall emulation callback handler adds one argument to each
+ * system call, so we'll need to allocate space for one more argument
+ * above the maximum number of arguments that a system call can normally
+ * take.  Also, we assume that each syscall argument is a long, ie, we
+ * don't support long long syscall parameters.
+ */
+#if defined(__sparc)
+/*
+ * 32-bit and 64-bit sparc syscalls can take up to 8 arguments.
+ * 32-bit sparc indirect syscalls can take up to 9 arguments.
+ * Arguments 1 - 6 are passed via %o0 - %o5.
+ * Additional arguments are passed on the stack.
+ * So make space for 4 arguments on the stack.
+ */
+#define	EH_ARGS_COUNT		4
+#elif defined(__amd64)
+/*
+ * amd64 syscalls can take up to 8 arguments.
+ * Arguments 1 - 6 are passed via: %rdi, %rsi, %rdx, %r10, %r8, %r9
+ * Additional arguments are passed on the stack.
+ * So make space for 3 arguments on the stack.
+ */
+#define	EH_ARGS_COUNT		3
+#else /* !__sparc && !__amd64 */
+/*
+ * ia32 syscalls can take up to 8 arguments.
+ * All arguments are passed on the stack.
+ * So make space for 9 arguments on the stack.
+ */
+#define	EH_ARGS_COUNT		9
+#endif /* !__sparc && !__amd64 */
+
+
+#define	EH_ARGS_SIZE		(CPTRSIZE * EH_ARGS_COUNT)
+#define	EH_ARGS_OFFSET(x)	(STACK_BIAS + MINFRAME + (CPTRSIZE * (x)))
+#define	EH_LOCALS_SIZE		(EH_ARGS_SIZE + SIZEOF_GREGSET_T + \
+				    SIZEOF_SYSRET_T + CPTRSIZE)
+
+#if defined(__sparc)
+/*
+ * On sparc, all emulation callback handler variable access is done
+ * relative to %sp, so access offsets are positive.
+ */
+#define	EH_LOCALS_START		(STACK_BIAS + MINFRAME + EH_ARGS_SIZE)
+#define	EH_LOCALS_END_TGT	(STACK_BIAS + MINFRAME + EH_LOCALS_SIZE)
+#else /* !__sparc */
+/*
+ * On x86, all emulation callback handler variable access is done
+ * relative to %ebp/%rbp, so access offsets are negative.
+ */
+#define	EH_LOCALS_START		(-(EH_LOCALS_SIZE - \
+				    (STACK_BIAS + MINFRAME + EH_ARGS_SIZE)))
+#define	EH_LOCALS_END_TGT	0
+#endif /* !__sparc */
+
+/*
+ * In our emulation callback handler, our stack will look like:
+ *		-------------------------------------------------
+ *	  %bp   | long		rvflag				|
+ *	   |    | sysret_t	sysret				|
+ *	   v    | gregset_t	gregs				|
+ *	  %sp   | long		callback args[EH_ARGS_COUNT]	|
+ *		-------------------------------------------------
+ * For ia32, use %ebp and %esp instead of %bp and %sp.
+ * For amd64, use %rbp and %rsp instead of %bp and %sp.
+ *
+ * Our emulation callback handler always saves enough space to hold the
+ * maximum number of stack arguments to a system call.  This is architecture
+ * specific and is defined via EH_ARGS_COUNT.
+ */
+#define	EH_LOCALS_GREGS		(EH_LOCALS_START)
+#define	EH_LOCALS_GREG(x)	(EH_LOCALS_GREGS + (SIZEOF_GREG_T * (x)))
+#define	EH_LOCALS_SYSRET	(EH_LOCALS_GREGS + SIZEOF_GREGSET_T)
+#define	EH_LOCALS_SYSRET1	(EH_LOCALS_SYSRET)
+#define	EH_LOCALS_SYSRET2	(EH_LOCALS_SYSRET + CPTRSIZE)
+#define	EH_LOCALS_RVFLAG	(EH_LOCALS_SYSRET + SIZEOF_SYSRET_T)
+#define	EH_LOCALS_END		(EH_LOCALS_RVFLAG + CPTRSIZE)
+
+#if (EH_LOCALS_END != EH_LOCALS_END_TGT)
+#error "s10_misc.h EH_LOCALS_* macros don't add up"
+#endif /* (EH_LOCALS_END != EH_LOCALS_END_TGT) */
+
+/*
+ * The second parameter of each entry in the s10_sysent_table
+ * contains the number of parameters and flags that describe the
+ * syscall return value encoding.  See the block comments at the
+ * top of ../common/s10_brand.c for more information about the
+ * syscall return value flags and when they should be used.
+ */
+#define	NARGS_MASK	0x000000FF	/* Mask for syscalls argument count */
+#define	RV_MASK		0x0000FF00	/* Mask for return value flags */
+#define	RV_DEFAULT	0x00000100	/* syscall returns "default" values */
+#define	RV_32RVAL2	0x00000200	/* syscall returns two 32-bit values */
+#define	RV_64RVAL	0x00000400	/* syscall returns a 64-bit value */
+
+#if !defined(_ASM)
+
+/*
+ * We define our own version of assert because the default one will
+ * try to emit a localized message.  That is bad because first, we can't
+ * emit messages to random file descriptors, and second localizing a message
+ * requires allocating memory and we can't do that either.
+ */
+#define	s10_assert(ex)	(void)((ex) || \
+				(_s10_abort(0, #ex, __FILE__, __LINE__), 0))
+#define	s10_abort(err, msg)	_s10_abort((err), (msg), __FILE__, __LINE__)
+
+/*
+ * These macros invoke a brandsys subcommand, B_S10_TRUSS_POINT, used to expose
+ * a call to an interpositioned syscall that would have otherwise gone
+ * unnoticed by truss(1) because the interpositioned system call did not call
+ * any system calls before returning.
+ */
+#define	S10_TRUSS_POINT_5(rval, syscall_num, err, a0, a1, a2, a3, a4) \
+	__systemcall(rval, SYS_brand + 1024, \
+	    B_S10_TRUSS_POINT, (syscall_num), (err), (a0), (a1), (a2), (a3), \
+	    (a4))
+
+#define	S10_TRUSS_POINT_4(rval, syscall_num, err, a0, a1, a2, a3) \
+	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), (a3), 0)
+
+#define	S10_TRUSS_POINT_3(rval, syscall_num, err, a0, a1, a2) \
+	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), 0, 0)
+
+#define	S10_TRUSS_POINT_2(rval, syscall_num, err, a0, a1) \
+	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), 0, 0, 0)
+
+#define	S10_TRUSS_POINT_1(rval, syscall_num, err, a0) \
+	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), 0, 0, 0, 0)
+
+#define	S10_TRUSS_POINT_0(rval, syscall_num, err) \
+	S10_TRUSS_POINT_5(rval, (syscall_num), (err), 0, 0, 0, 0, 0)
+
+/*
+ * From s10_runexe.s
+ */
+extern void s10_runexe(void *, ulong_t);
+
+/*
+ * From s10_handler.s
+ */
+extern void s10_handler(void);
+extern void s10_error(void);
+extern void s10_success(void);
+
+/*
+ * From s10_brand.c
+ */
+extern void _s10_abort(int, const char *, const char *, int);
+
+#endif	/* !_ASM */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _S10_MISC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include $(SRC)/lib/Makefile.lib
+
+default:	all
+
+SUBDIRS =	$(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all :=		TARGET= all
+clean :=	TARGET= clean
+clobber :=	TARGET= clobber
+install :=	TARGET= install
+lint :=		TARGET= lint
+_msg :=		TARGET= _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint _msg: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/Makefile.com	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY =	s10_npreload.a
+VERS =		.1
+COBJS =		s10_npreload.o
+
+OBJECTS =	$(COBJS)
+
+UTSBASE =       $(SRC)/uts
+
+include ../../Makefile.s10
+include $(SRC)/lib/Makefile.lib
+
+LIBS =		$(DYNLIB)
+CSRCS =		$(COBJS:%o=../common/%c)
+SRCS =		$(CSRCS)
+SRCDIR =	../common
+
+CPPFLAGS +=	-D_REENTRANT -U_ASM -I../sys \
+		-I$(UTSBASE)/common/brand/solaris10
+CFLAGS +=	$(CCVERBOSE)
+DYNFLAGS +=	$(BLOCAL) $(ZNOVERSION)
+LDLIBS +=	-lc
+
+CLEANFILES +=	$(DYNLIB)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/amd64/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+CLOBBERFILES	= $(ROOTLIBDIR64)/$(DYNLIB) $(ROOTLIBDIR64)/$(LINTLIB)
+
+install: all $(ROOTLIBS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/common/mapfile-vers	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#    
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#    
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# MAPFILE HEADER START
+#
+# WARNING:  STOP NOW.  DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+#	usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+SUNWprivate_1.0 {
+    local:
+	*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma init(init)
+
+#include <s10_brand.h>
+#include <sys/syscall.h>
+
+/*
+ * This is a library that is LD_PRELOADed into native binaries.
+ * All it does is one brand operation.  B_S10_NATIVE.  This brand
+ * operation checks that this is actually a native binary, and then
+ * if so changes the executable name so that it is no longer ld.sol.1.
+ * Instead it changes it to be the name of the real native executable
+ * that we're runnning.  This allows things like pgrep to work as
+ * expected.  Note, that this brand opration only changes the process
+ * name wrt the kernel.  From the processes perspective, the first
+ * argument and AT_SUN_EXECNAME are still ld.so.1.
+ */
+
+void
+init(void)
+{
+	sysret_t rval;
+	(void) __systemcall(&rval, SYS_brand, B_S10_NATIVE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/i386/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+CLOBBERFILES	= $(ROOTLIBDIR)/$(DYNLIB) $(ROOTLIBDIR)/$(LINTLIB)
+
+install: all $(ROOTLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/sparc/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+CLOBBERFILES +=	$(ROOTLIBS)
+
+install: all $(ROOTLIBS)
+
+include $(SRC)/Makefile.msg.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_npreload/sparcv9/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+CLOBBERFILES +=	$(ROOTLIBS64)
+
+install: all $(ROOTLIBS64)
+
+include $(SRC)/Makefile.msg.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_support/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,54 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROG =		s10_support
+PROGS =		$(PROG)
+OBJS =		s10_support
+
+all:		$(PROG)
+
+include ../Makefile.s10
+include $(SRC)/cmd/Makefile.cmd
+
+# override the install directory
+ROOTBIN =	$(ROOTBRANDDIR)
+CLOBBERFILES =	$(OBJS) $(ROOTPROGS)
+
+UTSBASE =	$(SRC)/uts
+
+CFLAGS +=	$(CCVERBOSE)
+CPPFLAGS +=	-D_REENTRANT -I$(UTSBASE)/common/brand/solaris10
+LDLIBS +=	-lzonecfg
+
+.KEEP_STATE:
+
+install:	all $(ROOTPROGS)
+
+clean:
+		$(RM) $(PROG) $(OBJS)
+
+lint:		lint_PROG
+
+include $(SRC)/cmd/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/s10_support/s10_support.c	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,457 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * s10_support is a small cli utility used to perform some brand-specific
+ * tasks when verifying a zone.  This utility is not intended to be called
+ * by users - it is intended to be invoked by the zones utilities.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <s10_brand.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <stropts.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/varargs.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <locale.h>
+#include <dirent.h>
+#include <sys/systeminfo.h>
+
+#include <libzonecfg.h>
+
+static void s10_err(char *msg, ...) __NORETURN;
+static void usage(void) __NORETURN;
+
+/*
+ * XXX This is a temporary flag for the initial release to enable the
+ * use of features which are not yet tested or fully implemented.
+ */
+static boolean_t override = B_FALSE;
+
+static char *bname = NULL;
+
+#define	PKGINFO_RD_LEN	128
+#define	PATCHLIST	"PATCHLIST="
+
+#if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
+#define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
+#endif
+
+/*PRINTFLIKE1*/
+static void
+s10_err(char *msg, ...)
+{
+	char	buf[1024];
+	va_list	ap;
+
+	va_start(ap, msg);
+	(void) vsnprintf(buf, sizeof (buf), msg, ap);
+	va_end(ap);
+
+	/* This needs go to stdout so the msgs show up through zoneadm. */
+	(void) printf("Error: %s\n", buf);
+
+	exit(1);
+	/*NOTREACHED*/
+}
+
+static int
+s10_verify(char *xmlfile)
+{
+	zone_dochandle_t	handle;
+	struct zone_fstab	fstab;
+	struct zone_devtab	devtab;
+	zone_iptype_t		iptype;
+	struct zone_dstab	dstab;
+
+	if ((handle = zonecfg_init_handle()) == NULL)
+		s10_err(gettext("internal libzonecfg.so.1 error"), 0);
+
+	if (zonecfg_get_xml_handle(xmlfile, handle) != Z_OK) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("zonecfg provided an invalid XML file"));
+	}
+
+	/*
+	 * Check to see whether the zone has any inherit-pkg-dirs
+	 * configured.
+	 */
+	if (zonecfg_setipdent(handle) != Z_OK) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("zonecfg provided an invalid XML file"));
+	}
+	if (zonecfg_getipdent(handle, &fstab) == Z_OK) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("solaris10 zones do not support "
+		    "inherit-pkg-dirs"));
+	}
+	(void) zonecfg_endipdent(handle);
+
+	/*
+	 * Check to see whether the zone has any unsupported devices
+	 * configured.
+	 *
+	 * The audio framework has changed in Solaris Next as compared to
+	 * S10.  Data indicates the less than 1/10 of 1 percent of zones
+	 * are using /dev/sound.  Given the low usage vs. the effort to
+	 * provide emulation, /dev/sound is currently disallowed.  We can
+	 * revisit this if there is enough demand.
+	 */
+	if (zonecfg_setdevent(handle) != Z_OK) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("zonecfg provided an invalid XML file"));
+	}
+	if (zonecfg_getdevent(handle, &devtab) == Z_OK) {
+		if (strncmp(devtab.zone_dev_match, "/dev/sound", 10) == 0 &&
+		    !override) {
+			zonecfg_fini_handle(handle);
+			s10_err(gettext("solaris10 zones do not currently "
+			    "support /dev/sound"));
+		}
+	}
+	(void) zonecfg_enddevent(handle);
+
+	/*
+	 * Check to see whether the zone has any experimental features
+	 * configured.
+	 */
+	if (zonecfg_get_iptype(handle, &iptype) == Z_OK &&
+	    iptype == ZS_EXCLUSIVE && !override) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("solaris10 zones do not currently support "
+		    "exclusive ip-type stacks"));
+	}
+
+	if (zonecfg_setdsent(handle) != Z_OK) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("zonecfg provided an invalid XML file"));
+	}
+	if (zonecfg_getdsent(handle, &dstab) == Z_OK && !override) {
+		zonecfg_fini_handle(handle);
+		s10_err(gettext("solaris10 zones do not currently support "
+		    "delegated datasets"));
+	}
+	(void) zonecfg_enddsent(handle);
+
+	zonecfg_fini_handle(handle);
+	return (0);
+}
+
+/*
+ * Read an entry from a pkginfo file.  Some of these lines can
+ * either be arbitrarily long or be continued by a backslash at the end of
+ * the line.  This function coalesces lines that are longer than the read
+ * buffer, and lines that are continued, into one buffer which is returned.
+ * The caller must free this memory.  NULL is returned when we hit EOF or
+ * if we run out of memory (errno is set to ENOMEM).
+ */
+static char *
+read_pkg_data(FILE *fp)
+{
+	char *start;
+	char *inp;
+	char *p;
+	int char_cnt = 0;
+
+	errno = 0;
+	if ((start = (char *)malloc(PKGINFO_RD_LEN)) == NULL) {
+		errno = ENOMEM;
+		return (NULL);
+	}
+
+	inp = start;
+	while ((p = fgets(inp, PKGINFO_RD_LEN, fp)) != NULL) {
+		int len;
+
+		len = strlen(inp);
+		if (inp[len - 1] == '\n' &&
+		    (len == 1 || inp[len - 2] != '\\')) {
+			char_cnt = len;
+			break;
+		}
+
+		if (inp[len - 1] == '\n' && inp[len - 2] == '\\')
+			char_cnt += len - 2;
+		else
+			char_cnt += PKGINFO_RD_LEN - 1;
+
+		if ((p = realloc(start, char_cnt + PKGINFO_RD_LEN)) == NULL) {
+			errno = ENOMEM;
+			break;
+		}
+
+		start = p;
+		inp = start + char_cnt;
+	}
+
+	if (errno == ENOMEM || (p == NULL && char_cnt == 0)) {
+		free(start);
+		start = NULL;
+	}
+
+	return (start);
+}
+
+/*
+ * Read the SUNWcakr pkginfo file and get the PATCHLIST for the pkg.
+ */
+static int
+get_ku_patchlist(char *zonename, char **patchlist)
+{
+	char		zonepath[MAXPATHLEN];
+	char		pkginfo[MAXPATHLEN];
+	FILE		*fp;
+	char		*buf;
+	int		err = 0;
+
+	if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK)
+		s10_err(gettext("error getting zone's path"));
+
+	if (snprintf(pkginfo, sizeof (pkginfo),
+	    "%s/root/var/sadm/pkg/SUNWcakr/pkginfo", zonepath)
+	    >= sizeof (pkginfo))
+		s10_err(gettext("error formating pkg path"));
+
+	if ((fp = fopen(pkginfo, "r")) == NULL)
+		return (errno);
+
+	while ((buf = read_pkg_data(fp)) != NULL) {
+		if (strncmp(buf, PATCHLIST, sizeof (PATCHLIST) - 1) == 0) {
+			int len;
+
+			/* remove trailing newline */
+			len = strlen(buf);
+			buf[len - 1] = '\0';
+
+			if ((*patchlist =
+			    strdup(buf + sizeof (PATCHLIST) - 1)) == NULL)
+				err = ENOMEM;
+
+			free(buf);
+			break;
+		}
+
+		free(buf);
+	}
+	(void) fclose(fp);
+
+	return (err);
+}
+
+/*
+ * Verify that we have the minimum KU needed.
+ * Note that KU patches are accumulative so future KUs will still deliver
+ * 141444 or 141445.
+ */
+static boolean_t
+have_valid_ku(char *zonename)
+{
+	char		*p;
+	char		*lastp;
+	char		*pstr;
+	char		*patchlist = NULL;
+	int		i;
+	char 		*vers_table[] = {
+			    "141444-09",
+			    "141445-09",
+			    NULL};
+
+	if (get_ku_patchlist(zonename, &patchlist) != 0 || patchlist == NULL)
+		return (B_FALSE);
+
+	pstr = patchlist;
+	while ((p = strtok_r(pstr, " ", &lastp)) != NULL) {
+		for (i = 0; vers_table[i] != NULL; i++)
+			if (strcmp(p, vers_table[i]) == 0)
+				return (B_TRUE);
+
+		pstr = NULL;
+	}
+
+	return (B_FALSE);
+}
+
+/*
+ * Get the emulation version from the /usr/lib/brand/solaris10/version file
+ * in either the global zone or the non-global zone.
+ */
+static int
+get_emul_version_number(char *verspath)
+{
+	int	vers = 0;
+	FILE	*fp;
+	char	buf[LINE_MAX];
+
+	/* If the file doesn't exist, assume version 0 */
+	if ((fp = fopen(verspath, "r")) == NULL)
+		return (vers);
+
+	while (fgets(buf, sizeof (buf), fp) != NULL) {
+		if (buf[0] == '#')
+			continue;
+
+		errno = 0;
+		vers = strtol(buf, (char **)NULL, 10);
+		if (errno != 0) {
+			(void) fclose(fp);
+			s10_err(gettext("error reading minimum version"));
+		}
+	}
+
+	(void) fclose(fp);
+
+	return (vers);
+}
+
+/*
+ * Get the current emulation version that is implemented.
+ */
+static int
+get_current_emul_version()
+{
+	return (get_emul_version_number("/usr/lib/brand/solaris10/version"));
+}
+
+/*
+ * Get the emulation version that the S10 image requires.  This
+ * reads the optional /usr/lib/brand/solaris10/version file that might
+ * exist on Solaris 10.  That file specifies the minimal solaris10 brand
+ * emulation version that the specific release of S10 requires.  If no
+ * minimal version is specified, the initial emulation remains compatible.
+ *
+ * If a new KU patch is created which needs different handling by the
+ * emulation, then the S10 /usr/lib/brand/solaris10/version file should be
+ * updated to specify a new version.
+ */
+static int
+get_image_emul_rqd_version(char *zonename)
+{
+	char	zonepath[MAXPATHLEN];
+	char	verspath[MAXPATHLEN];
+
+	if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK)
+		s10_err(gettext("error getting zone's path"));
+
+	if (snprintf(verspath, sizeof (verspath),
+	    "%s/root/usr/lib/brand/solaris10/version",
+	    zonepath) >= sizeof (verspath))
+		s10_err(gettext("error formating version path"));
+
+	return (get_emul_version_number(verspath));
+}
+
+static void
+fail_xvm()
+{
+	char buf[80];
+
+	if (sysinfo(SI_PLATFORM, buf, sizeof (buf)) != -1 &&
+	    strcmp(buf, "i86xpv") == 0 && !override)
+		s10_err(gettext("running the solaris10 brand "
+		    "in a paravirtualized\ndomain is currently not supported"));
+}
+
+static int
+s10_boot(char *zonename)
+{
+	zoneid_t zoneid;
+	int emul_vers;
+	int rqd_emul_vers;
+
+	if (!have_valid_ku(zonename))
+		s10_err(gettext("The installed version of Solaris 10 is "
+		    "not supported"));
+
+	emul_vers = get_current_emul_version();
+	rqd_emul_vers = get_image_emul_rqd_version(zonename);
+
+	if (rqd_emul_vers > emul_vers)
+		s10_err(gettext("The zone's version of Solaris 10 is "
+		    "incompatible with the current version of the solaris10 "
+		    "brand."));
+
+	if ((zoneid = getzoneidbyname(zonename)) < 0)
+		s10_err(gettext("unable to get zoneid"));
+
+	if (zone_setattr(zoneid, S10_EMUL_VERSION_NUM, &rqd_emul_vers,
+	    sizeof (int)) == -1)
+		s10_err(gettext("error setting zone's emulation version "
+		    "property"));
+
+	fail_xvm();
+
+	return (0);
+}
+
+static void
+usage()
+{
+	(void) fprintf(stderr, gettext(
+	    "usage:\t%s verify <xml file>\n"
+	    "\t%s boot\n"),
+	    bname, bname);
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	(void) setlocale(LC_ALL, "");
+	(void) textdomain(TEXT_DOMAIN);
+
+	bname = basename(argv[0]);
+
+	if (argc != 3)
+		usage();
+
+	/*
+	 * XXX This is a temporary env variable for the initial release to
+	 * enable the use of features which are not yet tested or fully
+	 * implemented.
+	 */
+	if (getenv("S10BRAND_TEST") != NULL)
+		override = B_TRUE;
+
+	if (strcmp(argv[1], "verify") == 0)
+		return (s10_verify(argv[2]));
+
+	if (strcmp(argv[1], "boot") == 0)
+		return (s10_boot(argv[2]));
+
+	usage();
+	/*NOTREACHED*/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROGS =		attach clone detach image_install p2v poststate prestate \
+		s10_boot uninstall
+XMLDOCS=	config.xml platform.xml smf_disable.lst pkgrm.lst common.ksh \
+		version
+USERFILES=	smf_disable.conf pkgrm.conf
+TEMPLATES =	SUNWsolaris10.xml
+CLOBBERFILES=	$(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ETCUSER)
+
+include $(SRC)/cmd/Makefile.cmd
+include ../Makefile.s10
+
+.KEEP_STATE:
+
+all:	$(PROGS)
+
+POFILES =	$(PROGS:%=%.po) common.po
+POFILE =	s10_zone.po
+
+$(POFILE): $(POFILES)
+	$(RM) $@
+	$(CAT) $(POFILES) > $@
+
+install: $(PROGS) $(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ETCUSER)
+
+lint:
+
+clean:
+	-$(RM) $(PROGS) $(POFILES) $(POFILE)
+
+include $(SRC)/cmd/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/SUNWsolaris10.xml	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+    DO NOT EDIT THIS FILE.  Use zonecfg(1M) instead.
+-->
+
+<!DOCTYPE zone PUBLIC "-//Sun Microsystems Inc//DTD Zones//EN" "file:///usr/share/lib/xml/dtd/zonecfg.dtd.1">
+
+<zone name="default" zonepath="" autoboot="false" brand="solaris10">
+</zone>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/attach.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,235 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+m_attach_log=$(gettext "Log File: %s")
+m_zfs=$(gettext "A ZFS file system was created for the zone.")
+m_attaching=$(gettext "Attaching...")
+m_usage=$(gettext  "solaris10 brand usage:\n\tattach [-a archive | -d directory | -r recv_type]\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -r recv_type option specifies the type of archive to be read from\n\tstdin.")
+m_complete=$(gettext "Attach complete.")
+
+install_fail=$(gettext  "*** Attach FAILED ***")
+
+f_n_unimpl=$(gettext "The -n option is not yet implemented.")
+f_zfs=$(gettext "Error creating a ZFS file system (%s) for the zone.")
+f_nodataset=$(gettext "Error: there is no ZFS file system for the zone.")
+f_zfsdestroy=$(gettext "Error destroying ZFS file system %s.")
+
+f_sanity_notzone=$(gettext "Error: this is a system image and not a zone image.")
+
+f_baddir=$(gettext "Invalid '%s' directory within the zone")
+
+# Clean up on interrupt
+trap_cleanup()
+{
+	msg=$(gettext "Installation cancelled due to interrupt.")
+	log "$msg"
+
+	# umount any mounted file systems
+	umnt_fs
+
+	trap_exit
+}
+
+# If the attach failed then clean up the ZFS datasets we created.
+trap_exit()
+{
+	if [[ $EXIT_CODE != $ZONE_SUBPROC_OK && "$install_media" != "-" ]]; then
+		/usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F
+	fi
+
+	exit $EXIT_CODE
+}
+
+EXIT_CODE=$ZONE_SUBPROC_USAGE
+install_media="-"
+
+trap trap_cleanup INT
+trap trap_exit EXIT
+
+# If we weren't passed at least two arguments, exit now.
+(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
+
+ZONENAME="$1"
+ZONEPATH="$2"
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+
+shift; shift	# remove ZONENAME and ZONEPATH from arguments array
+
+ZONEROOT="$ZONEPATH/root"
+logdir="$ZONEROOT/var/log"
+
+noexecute=0
+
+unset inst_type
+
+# Other brand attach options are invalid for this brand.
+while getopts "a:d:nr:" opt; do
+	case $opt in
+		a)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="archive"
+			install_media="$OPTARG"
+			;;
+		d)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="directory"
+			install_media="$OPTARG"
+			;;
+		n)	noexecute=1 ;;
+		r)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="stdin"
+			install_media="$OPTARG"
+			;;
+		?)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+		*)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+	esac
+done
+shift $((OPTIND-1))
+
+if [[ $noexecute == 1 && -n "$inst_type" ]]; then
+	fatal "$m_usage"
+fi
+
+if [ $noexecute -eq 1 ]; then
+	#
+	# The zone doesn't have to exist when the -n option is used, so do
+	# this work early.
+	#
+
+	# XXX do the sw validation for solaris10 minimal patch level to ensure
+	# everything will be ok.
+	EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+	fatal "$f_n_unimpl"
+fi
+
+EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+
+if [[ -z "$inst_type" ]]; then
+ 	inst_type="directory"
+
+elif [[ "$install_media" != "-" ]]; then
+	#
+	# If we're not using a pre-existing zone directory layout then create
+	# the zone datasets and mount them.
+	#
+	unset DATASET
+	pdir=$(/usr/bin/dirname $ZONEPATH)
+	zds=$(/usr/sbin/zfs list -H -t filesystem -o name $pdir 2>/dev/null)
+	if (( $? == 0 )); then
+		pnm=$(/usr/bin/basename $ZONEPATH)
+		/usr/sbin/zfs create "$zds/$pnm"
+		if (( $? == 0 )); then
+			vlog "$m_zfs"
+			DATASET="$zds/$pnm"
+		else
+			log "$f_zfs" "$zds/$pnm"
+		fi
+	fi
+
+	create_active_ds
+fi
+
+#
+# The zone's datasets are now in place, validate that things
+# are setup correctly.
+#
+
+get_zonepath_ds $zonepath
+
+/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
+if (( $? != 0 )); then
+	fail_fatal "$f_no_active_ds"
+else
+       	/usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \
+	    >/dev/null 2>&1
+       	/usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \
+	    >/dev/null 2>&1
+fi
+
+BENAME=zbe-0
+/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1
+if (( $? != 0 )); then
+	fail_fatal "$f_zfs_create"
+else
+       	/usr/sbin/zfs set $PROP_ACTIVE=on $ZONEPATH_DS/ROOT/$BENAME \
+	    >/dev/null 2>&1
+       	/usr/sbin/zfs set canmount=noauto $ZONEPATH_DS/ROOT/$BENAME \
+	    >/dev/null 2>&1
+       	/usr/sbin/zfs inherit mountpoint $ZONEPATH_DS/ROOT/$BENAME \
+	    >/dev/null 2>&1
+       	/usr/sbin/zfs inherit zoned $ZONEPATH_DS/ROOT/$BENAME \
+	    >/dev/null 2>&1
+fi
+
+LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $zonename.attach_log.XXXXXX)
+if [[ -z "$LOGFILE" ]]; then
+	fatal "$e_tmpfile"
+fi
+exec 2>>"$LOGFILE"
+log "$m_attach_log" "$LOGFILE"
+
+log "$m_attaching"
+install_image "$inst_type" "$install_media"
+
+mk_zone_dirs
+
+#
+# Perform a final check that this is really a zone image and not an archive of
+# a system image which would need p2v.  Check for a well-known S10 SMF service
+# that shouldn't exist in a zone.
+#
+if [[ -e $ZONEROOT/var/svc/manifest/system/sysevent.xml ]]; then
+	log "$f_sanity_notzone"
+	exit $ZONE_SUBPROC_NOTCOMPLETE
+fi
+
+EXIT_CODE=$ZONE_SUBPROC_OK
+
+log "$m_complete"
+
+zone_logfile="${logdir}/$zonename.attach$$.log"
+
+safe_dir /var
+safe_dir /var/log
+safe_copy $LOGFILE $zone_logfile
+
+log "$m_attach_log" "$zone_logfile"
+rm -f $LOGFILE
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/clone.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,137 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+m_usage=$(gettext "solaris10 brand usage: clone {sourcezone}.")
+f_nosource=$(gettext "Error: unable to determine source zone dataset.")
+f_sysunconfig=$(gettext "Error: sys-unconfig failed.")
+
+# Set up ZFS dataset hierarchy for the zone.
+
+ROOT="rpool/ROOT"
+
+# Other brand clone options are invalid for this brand.
+while getopts "R:z:" opt; do
+	case $opt in
+		R)	ZONEPATH="$OPTARG" ;;
+		z)	ZONENAME="$OPTARG" ;;
+		*)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+	esac
+done
+shift $((OPTIND-1))
+
+if [ $# -ne 1 ]; then
+	fail_usage "$0 {sourcezone}";
+fi
+
+sourcezone=$1
+
+# Find the active source zone dataset to clone.
+sourcezonepath=`/usr/sbin/zonecfg -z $sourcezone info zonepath | \
+    /usr/bin/cut -f2 -d' '`
+if [ -z "$sourcezonepath" ]; then
+	fail_fatal "$f_nosource"
+fi
+
+get_zonepath_ds $sourcezonepath
+get_active_ds $ZONEPATH_DS
+
+#
+# Now set up the zone's datasets
+#
+
+#
+# First make the top-level dataset.
+#
+
+pdir=`/usr/bin/dirname $ZONEPATH`
+zpname=`/usr/bin/basename $ZONEPATH`
+
+get_zonepath_ds $pdir
+zpds=$ZONEPATH_DS
+
+# Create the datasets.
+/usr/sbin/zfs create $zpds/$zpname
+if (( $? != 0 )); then
+	fail_fatal "$f_zfs_create"
+fi
+
+/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $zpds/$zpname/ROOT
+if (( $? != 0 )); then
+	fail_fatal "$f_zfs_create"
+fi
+
+# make snapshot
+SNAPNAME=${ZONENAME}_snap
+SNAPNUM=0
+while [ $SNAPNUM -lt 100 ]; do
+	/usr/sbin/zfs snapshot $ACTIVE_DS@$SNAPNAME
+        if [ $? = 0 ]; then
+                break
+	fi
+	SNAPNUM=`expr $SNAPNUM + 1`
+	SNAPNAME="${ZONENAME}_snap$SNAPNUM"
+done
+
+if [ $SNAPNUM -ge 100 ]; then
+	fail_fatal "$f_zfs_create"
+fi
+
+# do clone
+BENAME=zbe-0
+/usr/sbin/zfs clone -o $PROP_ACTIVE=on -o canmount=noauto \
+     $ACTIVE_DS@$SNAPNAME $zpds/$zpname/ROOT/$BENAME
+if (( $? != 0 )); then
+	fail_fatal "$f_zfs_create"
+fi
+
+if [ ! -d $ZONEPATH/root ]; then
+	/usr/bin/mkdir -p $ZONEPATH/root || \
+	    fail_fatal "$f_mkdir" "$ZONEPATH/root"
+	/usr/bin/chmod 700 $ZONEPATH || \
+	    fail_fatal "$f_chmod" "$ZONEPATH"
+fi
+
+# Don't re-sysunconfig if we've already done so
+if [[ ! -f $ZONEROOT/etc/.UNCONFIGURED ]]; then
+	/usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none
+	if (( $? != 0 )); then
+		error "$e_badboot"
+		fail_incomplete "$f_sysunconfig"
+	fi
+
+	sysunconfig_zone
+	if (( $? != 0 )); then
+		/usr/sbin/zoneadm -z $ZONENAME halt
+		fail_incomplete "$f_sysunconfig"
+	fi
+
+	/usr/sbin/zoneadm -z $ZONENAME halt
+fi
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/common.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,333 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+
+# Use the ipkg-brand ZFS property for denoting the zone root's active dataset.
+PROP_ACTIVE="org.opensolaris.libbe:active"
+
+f_sanity_detail=$(gettext  "Missing %s at %s")
+f_sanity_sparse=$(gettext  "Is this a sparse zone image?  The image must be whole-root.")
+f_sanity_vers=$(gettext  "The image release version must be 10 (got %s), the zone is not usable on this system.")
+f_not_s10_image=$(gettext  "%s doesn't look like a Solaris 10 image.")
+f_sanity_nopatch=$(gettext "Unable to determine the image's patch level.")
+f_sanity_downrev=$(gettext "The image patch level is downrev for running in a solaris10 branded zone.\n(patchlist %s)")
+f_need_newer_emul=$(gettext "The image requires a newer version of the solaris10 brand emulation.")
+f_zfs_create=$(gettext "Unable to create the zone's ZFS dataset.")
+f_no_ds=$(gettext "No zonepath dataset; the zonepath must be a ZFS dataset.")
+f_multiple_ds=$(gettext "Multiple active datasets.")
+f_no_active_ds=$(gettext "No active dataset; the zone's ZFS root dataset must be configured as\n\ta zone boot environment.")
+f_zfs_unmount=$(gettext "Unable to unmount the zone's root ZFS dataset (%s).\nIs there a global zone process inside the zone root?\nThe current zone boot environment will remain mounted.\n")
+f_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
+incompat_options=$(gettext "mutually exclusive options.\n%s")
+
+sanity_ok=$(gettext     "  Sanity Check: Passed.  Looks like a Solaris 10 image.")
+sanity_fail=$(gettext   "  Sanity Check: FAILED (see log for details).")
+
+e_badboot=$(gettext "Zone boot failed")
+e_nosingleuser=$(gettext "ERROR: zone did not finish booting to single-user.")
+e_unconfig=$(gettext "sys-unconfig failed")
+v_unconfig=$(gettext "Performing zone sys-unconfig")
+
+sanity_check()
+{
+	typeset dir="$1"
+	res=0
+
+	#
+	# Check for some required directories and make sure this isn't a
+	# sparse zone image.
+	#
+	checks="etc etc/svc var var/svc"
+	for x in $checks; do
+		if [[ ! -e $dir/$x ]]; then
+			log "$f_sanity_detail" "$x" "$dir"
+			res=1
+		fi
+	done
+	# Files from SUNWcsr and SUNWcsu that are in sparse inherit-pkg-dirs.
+	checks="lib/svc sbin/zonename usr/bin/chmod"
+	for x in $checks; do
+		if [[ ! -e $dir/$x ]]; then
+			log "$f_sanity_detail" "$x" "$dir"
+			log "$f_sanity_sparse"
+			res=1
+		fi
+	done
+
+	#
+	# Check image release to be sure its S10.
+	#
+	image_vers="unknown"
+	if [[ -f $dir/var/sadm/system/admin/INST_RELEASE ]]; then
+		image_vers=$(nawk -F= '{if ($1 == "VERSION") print $2}' \
+		    $dir/var/sadm/system/admin/INST_RELEASE)
+	fi
+
+	if [[ "$image_vers" != "10" ]]; then
+		log "$f_sanity_vers" "$image_vers"
+		res=1
+	fi
+
+	#
+	# Make sure we have the minimal KU patch we support.  These are the
+	# KUs for S10u8.
+	#
+	if [[ $(uname -p) == "i386" ]]; then
+		req_patch="141445-09"
+	else
+		req_patch="141444-09"
+	fi
+
+	for i in $dir/var/sadm/pkg/SUNWcakr*
+	do
+		if [[ ! -d $i || ! -f $i/pkginfo ]]; then
+			log "$f_sanity_nopatch"
+			res=1
+		fi
+	done
+
+	#
+	# Check the core kernel pkg for the required KU patch.
+	#
+	found=0
+	for i in $dir/var/sadm/pkg/SUNWcakr*/pkginfo
+	do
+		patches=$(nawk -F= '{if ($1 == "PATCHLIST") print $2}' $i)
+		for patch in $patches
+		do
+			if [[ $patch == $req_patch ]]; then
+				found=1
+				break
+			fi
+		done
+
+		if (( $found == 1 )); then
+			break
+		fi
+	done
+
+	if (( $found != 1 )); then
+		log "$f_sanity_downrev" "$patches"
+		res=1
+	fi
+
+	#
+	# Check the S10 image for a required version of the emulation.
+	#
+	VERS_FILE=/usr/lib/brand/solaris10/version
+	s10vers_needs=0
+	if [[ -f $dir/$VERS_FILE ]]; then
+		s10vers_needs=$(/usr/bin/egrep -v "^#" $dir/$VERS_FILE)
+	fi
+
+	# Now get the current emulation version.
+	emul_vers=$(/usr/bin/egrep -v "^#" $VERS_FILE)
+
+	# Verify that the emulation can run this version of S10.
+	if (( $s10vers_needs > $emul_vers )); then
+		log "$f_need_newer_emul"
+		res=1
+	fi
+
+	if (( $res != 0 )); then
+		log "$sanity_fail"
+		fatal "$install_fail" "$ZONENAME"
+	fi
+
+	vlog "$sanity_ok"
+}
+
+# Find the active dataset under the zonepath dataset to mount on zonepath/root.
+# $1 ZONEPATH_DS
+get_active_ds() {
+	ACTIVE_DS=`/usr/sbin/zfs list -H -r -t filesystem \
+	    -o name,$PROP_ACTIVE $1/ROOT | \
+	    /usr/bin/nawk ' {
+		if ($1 ~ /ROOT\/[^\/]+$/ && $2 == "on") {
+			print $1
+			if (found == 1)
+				exit 1
+			found = 1
+		}
+	    }'`
+
+	if [ $? -ne 0 ]; then
+		fail_fatal "$f_multiple_ds"
+	fi
+
+	if [ -z "$ACTIVE_DS" ]; then
+		fail_fatal "$f_no_active_ds"
+	fi
+}
+
+#
+# Make sure the active dataset is mounted for the zone.  There are several
+# cases to consider:
+# 1) First boot of the zone, nothing is mounted
+# 2) Zone is halting, active dataset remains the same.
+# 3) Zone is halting, there is a new active dataset to mount.
+#
+mount_active_ds() {
+	mount -p | cut -d' ' -f3 | egrep -s "^$zonepath/root$"
+	if (( $? == 0 )); then
+		# Umount current dataset on the root (it might be an old BE).
+		/usr/sbin/umount $zonepath/root
+		if (( $? != 0 )); then
+			# The umount failed, leave the old BE mounted.  If
+			# there are zone processes (i.e. zsched) in the fs,
+			# then we're umounting because we failed validation
+			# during boot, otherwise, warn about gz process
+			# preventing umount.
+			nproc=`pgrep -z $zonename | wc -l`
+			if (( $nproc == 0 )); then
+                       		printf "$f_zfs_unmount" "$zonepath/root"
+			fi
+			return
+		fi
+	fi
+
+	# Mount active dataset on the root.
+	get_zonepath_ds $zonepath
+	get_active_ds $ZONEPATH_DS
+
+	/usr/sbin/mount -F zfs $ACTIVE_DS $zonepath/root || \
+	    fail_fatal "$f_zfs_mount"
+}
+
+#
+# Set up ZFS dataset hierarchy for the zone root dataset.
+#
+create_active_ds() {
+	# Find the zone's current dataset.  This should have been created by
+	# zoneadm (or the attach hook).
+	get_zonepath_ds $zonepath
+
+	#
+	# We need to tolerate errors while creating the datasets and making the
+	# mountpoint, since these could already exist from an attach scenario.
+	#
+
+	/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
+	if (( $? != 0 )); then
+		/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on \
+		    $ZONEPATH_DS/ROOT
+		if (( $? != 0 )); then
+			fail_fatal "$f_zfs_create"
+		fi
+	else
+	       	/usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \
+		    >/dev/null 2>&1
+	       	/usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \
+		    >/dev/null 2>&1
+	fi
+
+	BENAME=zbe-0
+	/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1
+	if (( $? != 0 )); then
+	       	/usr/sbin/zfs create -o $PROP_ACTIVE=on -o canmount=noauto \
+		    $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1
+		if (( $? != 0 )); then
+			fail_fatal "$f_zfs_create"
+		fi
+	else
+	       	/usr/sbin/zfs set $PROP_ACTIVE=on $ZONEPATH_DS/ROOT/$BENAME \
+		    >/dev/null 2>&1
+	       	/usr/sbin/zfs set canmount=noauto $ZONEPATH_DS/ROOT/$BENAME \
+		    >/dev/null 2>&1
+	       	/usr/sbin/zfs inherit mountpoint $ZONEPATH_DS/ROOT/$BENAME \
+		    >/dev/null 2>&1
+	       	/usr/sbin/zfs inherit zoned $ZONEPATH_DS/ROOT/$BENAME \
+		    >/dev/null 2>&1
+	fi
+
+	if [ ! -d $ZONEROOT ]; then
+		/usr/bin/mkdir -m 0755 -p $ZONEROOT || \
+		    fail_fatal "$f_mkdir" "$ZONEROOT"
+	fi
+	/usr/bin/chmod 700 $ZONEPATH || fail_fatal "$f_chmod" "$ZONEPATH"
+
+	/usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $ZONEROOT || \
+		fail_fatal "$f_zfs_mount"
+}
+
+#
+# Before booting the zone we may need to create a few mnt points, just in
+# case they don't exist for some reason.
+#
+# Whenever we reach into the zone while running in the global zone we
+# need to validate that none of the interim directories are symlinks
+# that could cause us to inadvertently modify the global zone.
+#
+mk_zone_dirs() {
+	vlog "$v_mkdirs"
+	if [[ ! -f $ZONEROOT/tmp && ! -d $ZONEROOT/tmp ]]; then
+		mkdir -m 1777 -p $ZONEROOT/tmp || exit $EXIT_CODE
+	fi
+	if [[ ! -f $ZONEROOT/var/run && ! -d $ZONEROOT/var/run ]]; then
+		mkdir -m 1755 -p $ZONEROOT/var/run || exit $EXIT_CODE
+	fi
+	if [[ ! -f $ZONEROOT/var/tmp && ! -d $ZONEROOT/var/tmp ]]; then
+		mkdir -m 1777 -p $ZONEROOT/var/tmp || exit $EXIT_CODE
+	fi
+	if [[ ! -h $ZONEROOT/etc && ! -f $ZONEROOT/etc/mnttab ]]; then
+		/usr/bin/touch $ZONEROOT/etc/mnttab || exit $EXIT_CODE
+		/usr/bin/chmod 444 $ZONEROOT/etc/mnttab || exit $EXIT_CODE
+	fi
+	if [[ ! -f $ZONEROOT/proc && ! -d $ZONEROOT/proc ]]; then
+		mkdir -m 755 -p $ZONEROOT/proc || exit $EXIT_CODE
+	fi
+	if [[ ! -f $ZONEROOT/dev && ! -d $ZONEROOT/dev ]]; then
+		mkdir -m 755 -p $ZONEROOT/dev || exit $EXIT_CODE
+	fi
+	if [[ ! -h $ZONEROOT/etc && ! -h $ZONEROOT/etc/svc && \
+	    ! -d $ZONEROOT/etc/svc ]]; then
+		mkdir -m 755 -p $ZONEROOT/etc/svc/volatile || exit $EXIT_CODE
+	fi
+}
+
+#
+# We're sys-unconfig-ing the zone.  This will normally halt the zone, however
+# there are problems with sys-unconfig and it can hang when the zone is booted
+# to milestone=none.  Sys-unconfig also sometimes hangs halting the zone.
+# Thus, we take some care to workaround these sys-unconfig limitations.
+#
+# On entry we expect the zone to be booted.  We use sys-unconfig -R to make it
+# think its working on an alternate root and let the caller halt the zone.
+#
+sysunconfig_zone() {
+	/usr/sbin/zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /./ \
+	    >/dev/null 2>&1
+	if (( $? != 0 )); then
+		error "$e_unconfig"
+		return 1
+	fi
+
+	return 0
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/config.xml	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ Use is subject to license terms.
+
+ DO NOT EDIT THIS FILE.
+-->
+
+<!DOCTYPE brand PUBLIC "-//Sun Microsystems Inc//DTD Brands//EN"
+    "file:///usr/share/lib/xml/dtd/brand.dtd.1">
+
+<brand name="solaris10">
+	<modname>s10_brand</modname>
+	<initname>/sbin/init</initname>
+	<login_cmd>/usr/bin/login -z %Z -f %u</login_cmd>
+	<user_cmd>/usr/bin/getent passwd %u</user_cmd>
+
+	<install>/usr/lib/brand/solaris10/image_install %z %R</install>
+	<installopts>a:d:psuv</installopts>
+	<boot>/usr/lib/brand/solaris10/s10_boot %z %R</boot>
+	<sysboot>/usr/lib/brand/solaris10/prestate %z %R 2 0</sysboot>
+	<halt></halt>
+	<verify_cfg>/usr/lib/brand/solaris10/s10_support verify</verify_cfg>
+	<verify_adm></verify_adm>
+	<attach>/usr/lib/brand/solaris10/attach %z %R</attach>
+	<detach>/usr/lib/brand/solaris10/detach %z %R</detach>
+	<clone>/usr/lib/brand/solaris10/clone -z %z -R %R</clone>
+	<uninstall>/usr/lib/brand/solaris10/uninstall %z %R</uninstall>
+	<prestatechange>/usr/lib/brand/solaris10/prestate %z %R</prestatechange>
+	<poststatechange>/usr/lib/brand/solaris10/poststate %z %R</poststatechange>
+	<query>/usr/lib/brand/shared/query %z %R</query>
+
+	<privilege set="default" name="contract_event" />
+	<privilege set="default" name="contract_identity" />
+	<privilege set="default" name="contract_observer" />
+	<privilege set="default" name="file_chown" />
+	<privilege set="default" name="file_chown_self" />
+	<privilege set="default" name="file_dac_execute" />
+	<privilege set="default" name="file_dac_read" />
+	<privilege set="default" name="file_dac_search" />
+	<privilege set="default" name="file_dac_write" />
+	<privilege set="default" name="file_owner" />
+	<privilege set="default" name="file_setid" />
+	<privilege set="default" name="ipc_dac_read" />
+	<privilege set="default" name="ipc_dac_write" />
+	<privilege set="default" name="ipc_owner" />
+	<privilege set="default" name="net_bindmlp" />
+	<privilege set="default" name="net_icmpaccess" />
+	<privilege set="default" name="net_mac_aware" />
+	<privilege set="default" name="net_observability" />
+	<privilege set="default" name="net_privaddr" />
+	<privilege set="default" name="net_rawaccess" ip-type="exclusive" />
+	<privilege set="default" name="proc_chroot" />
+	<privilege set="default" name="sys_audit" />
+	<privilege set="default" name="proc_audit" />
+	<privilege set="default" name="proc_lock_memory" />
+	<privilege set="default" name="proc_owner" />
+	<privilege set="default" name="proc_setid" />
+	<privilege set="default" name="proc_taskid" />
+	<privilege set="default" name="sys_acct" />
+	<privilege set="default" name="sys_admin" />
+	<privilege set="default" name="sys_ip_config" ip-type="exclusive" />
+	<privilege set="default" name="sys_iptun_config" ip-type="exclusive" />
+	<privilege set="default" name="sys_mount" />
+	<privilege set="default" name="sys_nfs" />
+	<privilege set="default" name="sys_resource" />
+	<privilege set="default" name="sys_ppp_config" ip-type="exclusive" />
+
+	<privilege set="prohibited" name="dtrace_kernel" />
+	<privilege set="prohibited" name="proc_zone" />
+	<privilege set="prohibited" name="sys_config" />
+	<privilege set="prohibited" name="sys_devices" />
+	<privilege set="prohibited" name="sys_ip_config" ip-type="shared" />
+	<privilege set="prohibited" name="sys_linkdir" />
+	<privilege set="prohibited" name="sys_net_config" />
+	<privilege set="prohibited" name="sys_res_config" />
+	<privilege set="prohibited" name="sys_suser_compat" />
+	<privilege set="prohibited" name="xvm_control" />
+	<privilege set="prohibited" name="virt_manage" />
+	<privilege set="prohibited" name="sys_ppp_config" ip-type="shared" />
+
+	<privilege set="required" name="proc_exec" />
+	<privilege set="required" name="proc_fork" />
+	<privilege set="required" name="sys_ip_config" ip-type="exclusive" />
+	<privilege set="required" name="sys_mount" />
+</brand>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/detach.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,65 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+m_usage=$(gettext  "solaris10 brand usage: detach [-n].")
+
+EXIT_CODE=$ZONE_SUBPROC_USAGE
+
+# If we weren't passed at least two arguments, exit now.
+(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
+
+ZONENAME="$1"
+ZONEPATH="$2"
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+
+shift; shift	# remove ZONENAME and ZONEPATH from arguments array
+
+noexecute=0
+
+# Other brand attach options are invalid for this brand.
+while getopts "n" opt; do
+	case $opt in
+		n)	noexecute=1 ;;
+		?)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+		*)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+	esac
+done
+shift $((OPTIND-1))
+
+if [[ $noexecute == 1 ]]; then
+	cat /etc/zones/$ZONENAME.xml
+	exit $ZONE_SUBPROC_OK
+fi
+
+cp /etc/zones/$ZONENAME.xml $ZONEPATH/SUNWdetached.xml
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/image_install.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,258 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+m_usage=$(gettext "solaris10 brand usage:\n\tinstall -u | -p [-v | -s] -a archive | -d directory.\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -u option unconfigures the zone, -p preserves the configuration.")
+
+no_install=$(gettext "Could not create install directory '%s'")
+
+product_vers=$(gettext  "       Product: %s")
+install_vers=$(gettext  "     Installer: %s")
+install_zone=$(gettext  "          Zone: %s")
+install_path=$(gettext  "          Path: %s")
+installing=$(gettext    "    Installing: This may take several minutes...")
+no_installing=$(gettext "    Installing: Using pre-existing data in zonepath")
+install_prog=$(gettext  "    Installing: %s")
+
+install_fail=$(gettext  "        Result: *** Installation FAILED ***")
+install_log=$(gettext   "      Log File: %s")
+
+install_good=$(gettext  "        Result: Installation completed successfully.")
+
+unpack_done=$(gettext   " Unpack result: %d")
+
+sanity_ok=$(gettext     "  Sanity Check: Passed.  Looks like a Solaris 10 system.")
+sanity_fail=$(gettext   "  Sanity Check: FAILED (see log for details).")
+
+
+p2ving=$(gettext        "Postprocessing: This may take a while...")
+p2v_prog=$(gettext      "   Postprocess: ")
+p2v_done=$(gettext      "        Result: Postprocessing complete.")
+p2v_fail=$(gettext      "        Result: Postprocessing failed.")
+
+root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.")
+
+media_missing=\
+$(gettext "you must specify an installation source using '-a', '-d' or '-r'.\n%s")
+
+cfgchoice_missing=\
+$(gettext "you must specify -u (sys-unconfig) or -p (preserve identity).\n%s")
+
+mount_failed=$(gettext "ERROR: zonecfg(1M) 'fs' mount failed")
+
+not_flar=$(gettext "Input is not a flash archive")
+bad_flar=$(gettext "Flash archive is a corrupt")
+unknown_archiver=$(gettext "Archiver %s is not supported")
+
+# Clean up on interrupt
+trap_cleanup()
+{
+	msg=$(gettext "Installation cancelled due to interrupt.")
+	log "$msg"
+
+	# umount any mounted file systems
+	umnt_fs
+
+	trap_exit
+}
+
+# If the install failed then clean up the ZFS datasets we created.
+trap_exit()
+{
+	if (( $EXIT_CODE != $ZONE_SUBPROC_OK )); then
+		/usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F
+	fi
+
+	exit $EXIT_CODE
+}
+
+#
+# The main body of the script starts here.
+#
+# This script should never be called directly by a user but rather should
+# only be called by zoneadm to install a s10 system image into a zone.
+#
+
+#
+# Exit code to return if install is interrupted or exit code is otherwise
+# unspecified.
+#
+EXIT_CODE=$ZONE_SUBPROC_USAGE
+
+trap trap_cleanup INT
+trap trap_exit EXIT
+
+# If we weren't passed at least two arguments, exit now.
+(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
+
+ZONENAME="$1"
+ZONEPATH="$2"
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+
+ZONEROOT="$ZONEPATH/root"
+logdir="$ZONEROOT/var/log"
+
+shift; shift	# remove ZONENAME and ZONEPATH from arguments array
+
+unset inst_type
+unset msg
+unset silent_mode
+unset OPT_V
+
+#
+# It is worth noting here that we require the end user to pick one of
+# -u (sys-unconfig) or -p (preserve config).  This is because we can't
+# really know in advance which option makes a better default.  Forcing
+# the user to pick one or the other means that they will consider their
+# choice and hopefully not be surprised or disappointed with the result.
+#
+unset unconfig_zone
+unset preserve_zone
+
+while getopts "a:d:pr:suv" opt
+do
+	case "$opt" in
+		a)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="archive"
+			install_media="$OPTARG"
+			;;
+		d)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="directory"
+			install_media="$OPTARG"
+			;;
+		p)	preserve_zone="-p";;
+		r)
+			if [[ -n "$inst_type" ]]; then
+				fatal "$incompat_options" "$m_usage"
+			fi
+		 	inst_type="stdin"
+			install_media="$OPTARG"
+			;;
+		s)	silent_mode=1;;
+		u)	unconfig_zone="-u";;
+		v)	OPT_V="-v";;
+		*)	printf "$m_usage\n"
+			exit $ZONE_SUBPROC_USAGE;;
+	esac
+done
+shift OPTIND-1
+
+# The install can't be both verbose AND silent...
+if [[ -n $silent_mode && -n $OPT_V ]]; then
+	fatal "$incompat_options" "$m_usage"
+fi
+
+if [[ -z $install_media ]]; then
+	fatal "$media_missing" "$m_usage"
+fi
+
+# The install can't both preserve and unconfigure
+if [[ -n $unconfig_zone && -n $preserve_zone ]]; then
+	fatal "$incompat_options" "$m_usage"
+fi
+
+# Must pick one or the other.
+if [[ -z $unconfig_zone && -z $preserve_zone ]]; then
+	fatal "$cfgchoice_missing" "$m_usage"
+fi
+
+LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $ZONENAME.install_log.XXXXXX)
+if [[ -z "$LOGFILE" ]]; then
+	fatal "$e_tmpfile"
+fi
+zone_logfile="${logdir}/$ZONENAME.install$$.log"
+exec 2>>"$LOGFILE"
+log "$install_log" "$LOGFILE"
+
+vlog "Starting pre-installation tasks."
+
+#
+# From here on out, an unspecified exit or interrupt should exit with
+# ZONE_SUBPROC_NOTCOMPLETE, meaning a user will need to do an uninstall before
+# attempting another install, as we've modified the directories we were going
+# to install to in some way.
+#
+EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+
+create_active_ds
+
+vlog "Installation started for zone \"$ZONENAME\""
+install_image "$inst_type" "$install_media"
+
+log "$p2ving"
+vlog "running: p2v $OPT_V $unconfig_zone $ZONENAME $ZONEPATH"
+
+#
+# Run p2v.
+#
+# Getting the output to the right places is a little tricky because what
+# we want is for p2v to output in the same way the installer does: verbose
+# messages to the log file always, and verbose messages printed to the
+# user if the user passes -v.  This rules out simple redirection.  And
+# we can't use tee or other tricks because they cause us to lose the
+# return value from the p2v script due to the way shell pipelines work.
+#
+# The simplest way to do this seems to be to hand off the management of
+# the log file to the p2v script.  So we run p2v with -l to tell it where
+# to find the log file and then reopen the log (O_APPEND) when p2v is done.
+#
+/usr/lib/brand/solaris10/p2v -l "$LOGFILE" -m "$p2v_prog" \
+     $OPT_V $unconfig_zone $ZONENAME $ZONEPATH
+p2v_result=$?
+exec 2>>$LOGFILE
+
+if (( $p2v_result == 0 )); then
+	vlog "$p2v_done"
+else
+	log "$p2v_fail"
+	log ""
+	log "$install_fail"
+	log "$install_log" "$LOGFILE"
+	exit $ZONE_SUBPROC_FATAL
+fi
+
+log ""
+log "$install_good" "$ZONENAME"
+
+safe_dir /var
+safe_dir /var/log
+safe_copy $LOGFILE $zone_logfile
+
+log "$install_log" "$zone_logfile"
+rm -f $LOGFILE
+
+# This needs to be set since the exit trap handler is going run.
+EXIT_CODE=$ZONE_SUBPROC_OK
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/p2v.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,618 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# NOTE: this script runs in the global zone and touches the non-global
+# zone, so care should be taken to validate any modifications so that they
+# are safe.
+
+. /usr/lib/brand/solaris10/common.ksh
+
+LOGFILE=
+MSG_PREFIX="p2v: "
+EXIT_CODE=1
+
+usage()
+{
+	echo "$0 [-s] [-m msgprefix] [-u] [-v] [-b patchid]* zonename" >&2
+	exit $EXIT_CODE
+}
+
+# Clean up on interrupt
+trap_cleanup()
+{
+	msg=$(gettext "Postprocessing cancelled due to interrupt.")
+	error "$msg"
+
+	if (( $zone_is_running != 0 )); then
+		error "$e_shutdown" "$ZONENAME"
+		/usr/sbin/zoneadm -z $ZONENAME halt
+	fi
+
+	exit $EXIT_CODE
+}
+
+#
+# Disable any existing live-upgrade configuration.
+# We have already called safe_dir to validate the etc/lu directory.
+#
+fix_lu()
+{
+	ludir=$ZONEROOT/etc/lu
+
+	[[ ! -d $ludir ]] && return
+
+	safe_rm etc/lutab
+	safe_rm etc/lu/.BE_CONFIG
+	safe_rm etc/lu/.CURR_VARS
+	safe_rm etc/lu/ludb.local.xml
+	for i in $ludir/ICF* $ludir/vtoc* $ludir/GRUB*
+	do
+		nm=`basename $i`
+		safe_rm etc/lu/$nm
+	done
+}
+
+#
+# For an exclusive stack zone, fix up the network configuration files.
+# We need to do this even if unconfiguring the zone so sys-unconfig works
+# correctly.
+#
+fix_net()
+{
+	[[ "$STACK_TYPE" == "shared" ]] && return
+
+	NETIF_CNT=$(/usr/bin/ls $ZONEROOT/etc/hostname.* 2>/dev/null | \
+	    /usr/bin/wc -l)
+	if (( $NETIF_CNT != 1 )); then
+		vlog "$v_nonetfix"
+		return
+	fi
+
+	NET=$(LC_ALL=C /usr/sbin/zonecfg -z $ZONENAME info net)
+	if (( $? != 0 )); then
+		error "$e_badinfo" "net"
+		return
+	fi
+
+	NETIF=$(echo $NET | /usr/bin/nawk '{
+		for (i = 1; i < NF; i++) {
+			if ($i == "physical:") {
+				if (length(net) == 0) {
+					i++
+					net = $i
+				} else {
+					multiple=1
+				}
+			}
+		}
+	}
+	END {	if (!multiple)
+			print net
+	}')
+
+	if [[ -z "$NETIF" ]]; then
+		vlog "$v_nonetfix"
+		return
+	fi
+
+	OLD_HOSTNET=$(/usr/bin/ls $ZONEROOT/etc/hostname.*)
+	if [[ "$OLD_HOSTNET" != "$ZONEROOT/etc/hostname.$NETIF" ]]; then
+		safe_move $OLD_HOSTNET $ZONEROOT/etc/hostname.$NETIF
+	fi
+}
+
+#
+# Disable all of the shares since the zone cannot be an NFS server.
+# Note that we disable the various instances of the svc:/network/shares/group
+# SMF service in the fix_smf function. 
+#
+fix_nfs()
+{
+	zonedfs=$ZONEROOT/etc/dfs
+
+	[[ ! -d $zonedfs ]] && return
+
+	if [[ -h $zonedfs/dfstab || ! -f $zonedfs/dfstab ]]; then
+		error "$e_badfile" "/etc/dfs/dfstab"
+		return
+	fi
+
+	tmpfile=$(mktemp -t)
+	if [[ $? == 1 || -z "$tmpfile" ]]; then
+		error "$e_tmpfile"
+		return
+	fi
+
+	/usr/bin/nawk '{
+		if (substr($1, 0, 1) == "#") {
+			print $0
+		} else {
+			print "#", $0
+			modified=1
+		}
+	}
+	END {
+		if (modified == 1) {
+			printf("# Modified by p2v ")
+			system("/usr/bin/date")
+			exit 0
+		}
+		exit 1
+	}' $zonedfs/dfstab >>$tmpfile
+
+	if (( $? == 0 )); then
+		if [[ ! -f $zonedfs/dfstab.pre_p2v ]]; then
+			safe_copy $zonedfs/dfstab $zonedfs/dfstab.pre_p2v
+		fi
+		safe_copy $tmpfile $zonedfs/dfstab
+		chown root:sys $zonedfs/dfstab || \
+		    fail_fatal "$f_chown" "$zonedfs/dfstab"
+		chmod 644 $zonedfs/dfstab || \
+		    fail_fatal "$f_chmod" "$zonedfs/dfstab"
+	fi
+	/usr/bin/rm -f $tmpfile
+}
+
+#
+# Comment out most of the old mounts since they are either unneeded or
+# likely incorrect within a zone.  Specific mounts can be manually 
+# reenabled if the corresponding device is added to the zone.
+#
+fix_vfstab()
+{
+	if [[ -h $ZONEROOT/etc/vfstab || ! -f $ZONEROOT/etc/vfstab ]]; then
+		error "$e_badfile" "/etc/vfstab"
+		return
+	fi
+
+	tmpfile=$(mktemp -t)
+	if [[ $? == 1 || -z "$tmpfile" ]]; then
+		error "$e_tmpfile"
+		return
+	fi
+
+	/usr/bin/nawk '{
+		if (substr($1, 0, 1) == "#") {
+			print $0
+		} else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" ||
+		    $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" ||
+		    $4 == "nfs" || $4 == "lofs") {
+			print $0
+		} else {
+			print "#", $0
+			modified=1
+		}
+	}
+	END {
+		if (modified == 1) {
+			printf("# Modified by p2v ")
+			system("/usr/bin/date")
+			exit 0
+		}
+		exit 1
+	}' $ZONEROOT/etc/vfstab >>$tmpfile
+
+	if (( $? == 0 )); then
+		if [[ ! -f $ZONEROOT/etc/vfstab.pre_p2v ]]; then
+			safe_copy $ZONEROOT/etc/vfstab \
+			    $ZONEROOT/etc/vfstab.pre_p2v
+		fi
+		safe_copy $tmpfile $ZONEROOT/etc/vfstab
+		chown root:sys $ZONEROOT/etc/vfstab || \
+		    fail_fatal "$f_chown" "$ZONEROOT/etc/vfstab"
+		chmod 644 $ZONEROOT/etc/vfstab || \
+		    fail_fatal "$f_chmod" "$ZONEROOT/etc/vfstab"
+	fi
+	/usr/bin/rm -f $tmpfile
+}
+
+#
+# Collect the data needed to delete SMF services.  Since we're p2v-ing a
+# physical image there are SMF services which must be deleted.
+#
+fix_smf_pre_uoa()
+{
+	#
+	# Start by getting the svc manifests that are delivered by hollow
+	# pkgs then use 'svccfg inventory' to get the names of the svcs
+	# delivered by those manifests.  The svc names are saved into a
+	# temporary file.
+	#
+
+	SMFTMPFILE=$(mktemp -t smf.XXXXXX)
+	if [[ $? == 1 || -z "$SMFTMPFILE" ]]; then
+		error "$e_tmpfile"
+		return
+	fi
+
+	for i in $ZONEROOT/var/sadm/pkg/*
+	do
+		pkg=$(/usr/bin/basename $i)
+		[[ ! -f $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap ]] \
+		    && continue
+
+		/usr/bin/egrep -s "SUNW_PKG_HOLLOW=true" \
+		    $ZONEROOT/var/sadm/pkg/$pkg/pkginfo || continue
+
+		for j in $(/usr/bin/nawk '{if ($2 == "f" &&
+		    substr($4, 1, 17) == "var/svc/manifest/") print $4}' \
+		    $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap)
+		do
+			svcs=$(SVCCFG_NOVALIDATE=1 \
+			    SVCCFG_REPOSITORY=$ZONEROOT/etc/svc/repository.db \
+			    /usr/sbin/svccfg inventory $ZONEROOT/$j)
+			for k in $svcs
+			do
+				echo $k /$j >> $SMFTMPFILE
+			done
+		done
+	done
+}
+
+#
+# Delete or disable SMF services.
+# Zone is booted to milestone=none when this function is called.
+# Use the SMF data collected by fix_smf_pre_uoa() to delete the services.
+#
+fix_smf()
+{
+	# 
+	# Zone was already booted to milestone=none, wait until SMF door exists.
+	#
+	for i in 0 1 2 3 4 5 6 7 8 9
+	do
+		[[ -r $ZONEROOT/etc/svc/volatile/repository_door ]] && break
+		sleep 5
+	done
+
+	if [[ $i -eq 9 && ! -r $ZONEROOT/etc/svc/volatile/repository_door ]];
+	then
+		error "$e_nosmf"
+		/usr/bin/rm -f $SMFTMPFILE
+		return
+	fi
+
+	insttmpfile=$(mktemp -t instsmf.XXXXXX)
+	if [[ $? == 1 || -z "$insttmpfile" ]]; then
+		error "$e_tmpfile"
+		/usr/bin/rm -f $SMFTMPFILE
+		return
+	fi
+
+	vlog "$v_rmhollowsvcs"
+        while read fmri mfst
+	do
+		# Delete the svc.
+		vlog "$v_delsvc" "$fmri"
+		echo "/usr/sbin/svccfg delete -f $fmri"
+		echo "/usr/sbin/svccfg delhash -d $mfst"
+		echo "rm -f $mfst"
+	done < $SMFTMPFILE > $ZONEROOT/tmp/smf_rm
+
+	/usr/sbin/zlogin -S $ZONENAME /bin/sh /tmp/smf_rm >/dev/null 2>&1
+
+	/usr/bin/rm -f $SMFTMPFILE
+
+	# Get a list of the svcs that now exist in the zone.
+	LANG=C /usr/sbin/zlogin -S $ZONENAME /usr/bin/svcs -aH | \
+	    /usr/bin/nawk '{print $3}' >>$insttmpfile
+
+	[[ -n $LOGFILE ]] && \
+	    printf "[$(date)] ${MSG_PREFIX}${v_svcsinzone}\n" >&2
+	[[ -n $LOGFILE ]] && cat $insttmpfile >&2
+
+	#
+	# Fix network services if shared stack.
+	#
+	if [[ "$STACK_TYPE" == "shared" ]]; then
+		vlog "$v_fixnetsvcs"
+
+		NETPHYSDEF="svc:/network/physical:default"
+		NETPHYSNWAM="svc:/network/physical:nwam"
+
+		/usr/bin/egrep -s "$NETPHYSDEF" $insttmpfile
+		if (( $? == 0 )); then
+			vlog "$v_enblsvc" "$NETPHYSDEF"
+			/usr/sbin/zlogin -S $ZONENAME \
+			    /usr/sbin/svcadm enable $NETPHYSDEF || \
+			    error "$e_dissvc" "$NETPHYSDEF"
+		fi
+
+		/usr/bin/egrep -s "$NETPHYSNWAM" $insttmpfile
+		if (( $? == 0 )); then
+			vlog "$v_dissvc" "$NETPHYSNWAM"
+			/usr/sbin/zlogin -S $ZONENAME \
+			    /usr/sbin/svcadm disable $NETPHYSNWAM || \
+			    error "$e_enblsvc" "$NETPHYSNWAM"
+		fi
+
+		for i in $(/usr/bin/egrep network/routing $insttmpfile)
+		do
+			# Disable the svc.
+			vlog "$v_dissvc" "$i"
+			/usr/sbin/zlogin -S $ZONENAME \
+			    /usr/sbin/svcadm disable $i || \
+			    error "$e_dissvc" $i
+		done
+	fi
+
+	#
+	# Disable well-known services that don't run in a zone.
+	#
+	vlog "$v_rminvalidsvcs"
+	for i in $(/usr/bin/egrep -hv "^#" \
+	    /usr/lib/brand/solaris10/smf_disable.lst \
+	    /etc/brand/solaris10/smf_disable.conf)
+	do
+		# Skip svcs not installed in the zone.
+		/usr/bin/egrep -s "$i:" $insttmpfile || continue
+
+		# Disable the svc.
+		vlog "$v_dissvc" "$i"
+		/usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \
+		    error "$e_dissvc" $i
+	done
+
+	#
+	# Since zones can't be NFS servers, disable all of the instances of
+	# the shares svc.
+	#
+	for i in $(/usr/bin/egrep network/shares/group $insttmpfile)
+	do
+		vlog "$v_dissvc" "$i"
+		/usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \
+		    error "$e_dissvc" $i
+	done
+
+	/usr/bin/rm -f $insttmpfile
+}
+
+#
+# Remove well-known pkgs that do not work inside a zone.
+#
+rm_pkgs()
+{
+	/usr/bin/cat <<-EOF > $ZONEROOT/tmp/admin || fatal "$e_adminf"
+	mail=
+	instance=overwrite
+	partial=nocheck
+	runlevel=nocheck
+	idepend=nocheck
+	rdepend=nocheck
+	space=nocheck
+	setuid=nocheck
+	conflict=nocheck
+	action=nocheck
+	basedir=default
+	EOF
+
+	for i in $(/usr/bin/egrep -hv "^#" /usr/lib/brand/solaris10/pkgrm.lst \
+	    /etc/brand/solaris10/pkgrm.conf)
+	do
+		[[ ! -d $ZONEROOT/var/sadm/pkg/$i ]] && continue
+
+		vlog "$v_rmpkg" "$i"
+		/usr/sbin/zlogin -S $ZONENAME \
+		    /usr/sbin/pkgrm -na /tmp/admin $i >&2 || error "$e_rmpkg" $i
+	done
+}
+
+#
+# Zoneadmd writes a one-line index file into the zone when the zone boots,
+# so any information about installed zones from the original system will
+# be lost at that time.  Here we'll warn the sysadmin about any pre-existing
+# zones that they might want to clean up by hand, but we'll leave the zonepaths
+# in place in case they're on shared storage and will be migrated to
+# a new host.
+#
+warn_zones()
+{
+	zoneconfig=$ZONEROOT/etc/zones
+
+	[[ ! -d $zoneconfig ]] && return
+
+	if [[ -h $zoneconfig/index || ! -f $zoneconfig/index ]]; then
+		error "$e_badfile" "/etc/zones/index"
+		return
+	fi
+
+	NGZ=$(/usr/bin/nawk -F: '{
+		if (substr($1, 0, 1) == "#" || $1 == "global")
+			continue
+
+		if ($2 == "installed")
+			printf("%s ", $1)
+	}' $zoneconfig/index)
+
+	# Return if there are no installed zones to warn about.
+	[[ -z "$NGZ" ]] && return
+
+	log "$v_rmzones" "$NGZ"
+
+	NGZP=$(/usr/bin/nawk -F: '{
+		if (substr($1, 0, 1) == "#" || $1 == "global")
+			continue
+
+		if ($2 == "installed")
+			printf("%s ", $3)
+	}' $zoneconfig/index)
+
+	log "$v_rmzonepaths"
+
+	for i in $NGZP
+	do
+		log "    %s" "$i"
+	done
+}
+
+#
+# ^C Should cleanup; if the zone is running, it should try to halt it.
+#
+zone_is_running=0
+trap trap_cleanup INT
+
+#
+# Parse the command line options.
+#
+OPT_U=
+OPT_V=
+OPT_M=
+OPT_L=
+while getopts "uvm:l:" opt
+do
+	case "$opt" in
+		u)	OPT_U="-u";;
+		v)	OPT_V="-v";;
+		m)	MSG_PREFIX="$OPTARG"; OPT_M="-m \"$OPTARG\"";;
+		l)	LOGFILE="$OPTARG"; OPT_L="-l \"$OPTARG\"";;
+		*)	usage;;
+	esac
+done
+shift OPTIND-1
+
+(( $# < 1 )) && usage
+
+(( $# > 2 )) && usage
+
+[[ -n $LOGFILE ]] && exec 2>>$LOGFILE
+
+ZONENAME=$1
+ZONEPATH=$2
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+ZONEROOT=$ZONEPATH/root
+
+e_badinfo=$(gettext "Failed to get '%s' zone resource")
+e_badfile=$(gettext "Invalid '%s' file within the zone")
+v_mkdirs=$(gettext "Creating mount points")
+v_nonetfix=$(gettext "Cannot update /etc/hostname.{net} file")
+v_adjust=$(gettext "Updating the image to run within a zone")
+v_stacktype=$(gettext "Stack type '%s'")
+v_booting=$(gettext "Booting zone to single user mode")
+e_nosmf=$(gettext "SMF repository unavailable.")
+v_svcsinzone=$(gettext "The following SMF services are installed:")
+v_rmhollowsvcs=$(gettext "Deleting SMF services from hollow packages")
+v_fixnetsvcs=$(gettext "Adjusting network SMF services")
+v_rminvalidsvcs=$(gettext "Disabling invalid SMF services")
+v_delsvc=$(gettext "Delete SMF svc '%s'")
+e_delsvc=$(gettext "deleting SMF svc '%s'")
+v_enblsvc=$(gettext "Enable SMF svc '%s'")
+e_enblsvc=$(gettext "enabling SMF svc '%s'")
+v_dissvc=$(gettext "Disable SMF svc '%s'")
+e_dissvc=$(gettext "disabling SMF svc '%s'")
+e_adminf=$(gettext "Unable to create admin file")
+v_rmpkg=$(gettext "Remove package '%s'")
+e_rmpkg=$(gettext "removing package '%s'")
+v_rmzones=$(gettext "The following zones in this image will be unusable: %s")
+v_rmzonepaths=$(gettext "These zonepaths could be removed from this image:")
+v_halting=$(gettext "Halting zone")
+e_shutdown=$(gettext "Shutting down zone %s...")
+e_badhalt=$(gettext "Zone halt failed")
+v_exitgood=$(gettext "Postprocessing successful.")
+e_exitfail=$(gettext "Postprocessing failed.")
+
+#
+# Do some validation on the paths we'll be accessing
+#
+safe_dir /etc
+safe_dir /var
+safe_opt_dir /etc/dfs
+safe_opt_dir /etc/lu
+safe_opt_dir /etc/zones
+
+mk_zone_dirs
+
+# Now do the work to update the zone.
+
+# Check for zones inside of image.
+warn_zones
+fix_smf_pre_uoa
+
+log "$v_adjust"
+
+#
+# Any errors in these functions are not considered fatal.  The zone can be
+# be fixed up manually afterwards and it may need some additional manual
+# cleanup in any case.
+#
+
+STACK_TYPE=$(/usr/sbin/zoneadm -z $ZONENAME list -p | \
+    /usr/bin/nawk -F: '{print $7}')
+if (( $? != 0 )); then
+	error "$e_badinfo" "stacktype"
+fi
+vlog "$v_stacktype" "$STACK_TYPE"
+
+fix_lu
+fix_net
+fix_nfs
+fix_vfstab
+
+vlog "$v_booting"
+
+#
+# Boot the zone so that we can do all of the SMF updates needed on the zone's
+# repository.
+#
+
+zone_is_running=1
+
+/usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none
+if (( $? != 0 )); then
+	error "$e_badboot"
+	/usr/bin/rm -f $SMFTMPFILE
+	fatal "$e_exitfail"
+fi
+
+# cleanup SMF services
+fix_smf
+
+# remove invalid pkgs
+rm_pkgs
+
+if [[ -z $failed && -n $OPT_U ]]; then
+	vlog "$v_unconfig"
+
+	sysunconfig_zone
+	if (( $? != 0 )); then
+		failed=1
+	fi
+fi
+
+vlog "$v_halting"
+/usr/sbin/zoneadm -z $ZONENAME halt
+if (( $? != 0 )); then
+	error "$e_badhalt"
+	failed=1
+fi
+zone_is_running=0
+
+if [[ -n $failed ]]; then
+	fatal "$e_exitfail"
+fi
+
+vlog "$v_exitgood"
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/pkgrm.conf	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,28 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SVr4 packages which should be removed when installing
+# the zone.  Site-specific packages which must be removed should be listed
+# in this file.  During the zone installation, the packages will be removed
+# if they existed on the original physical system.
+# 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/pkgrm.lst	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SVr4 packages which should be removed when installing
+# the zone.  Do not edit this file.  Site-specific packages which must be
+# removed should be listed in the /etc/brand/solaris10/pkgrm.conf file.
+# During the zone installation, the packages will be removed if they existed
+# on the original physical system.
+# 
+VRTSvxvm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/platform.xml	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,151 @@
+<?xml version="1.0"?>
+
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ Use is subject to license terms.
+
+ DO NOT EDIT THIS FILE.
+-->
+
+<!DOCTYPE platform PUBLIC "-//Sun Microsystems Inc//Zones Platform//EN"
+    "file:///usr/share/lib/xml/dtd/zone_platform.dtd.1">
+
+<platform name="solaris10" allow-exclusive-ip="true">
+
+	<!-- Global filesystems to mount when booting the zone -->
+	<global_mount special="/dev" directory="/dev" type="dev"
+	    opt="attrdir=%R/dev"/>
+
+	<!--
+	    Local filesystems to mount when booting the zone.  The
+	    /.SUNWnative/platform entry is needed so that we can symlink a
+	    platform-specific libc_psr for platforms which were not delivered
+	    with S10.  The /.SUNWnative/sbin entry is needed so that we can
+	    replace ifconfig with its native counterpart (this is required for
+	    exclusive-stack S10 zones to work).
+	-->
+	<global_mount special="/usr" directory="/.SUNWnative/usr"
+	    opt="ro,nodevices" type="lofs" />
+	<global_mount special="/lib" directory="/.SUNWnative/lib"
+	    opt="ro,nodevices" type="lofs" />
+	<global_mount special="/platform" directory="/.SUNWnative/platform"
+	    opt="ro,nodevices" type="lofs" />
+	<global_mount special="/sbin" directory="/.SUNWnative/sbin"
+	    opt="ro,nodevices" type="lofs" />
+
+	<!-- Local filesystems to mount when booting the zone -->
+	<mount special="/proc" directory="/proc" type="proc" />
+	<mount special="ctfs" directory="/system/contract" type="ctfs" />
+	<mount special="mnttab" directory="/etc/mnttab" type="mntfs" />
+	<mount special="objfs" directory="/system/object" type="objfs" />
+	<mount special="swap" directory="/etc/svc/volatile" type="tmpfs" />
+
+	<!-- Devices to create under /dev -->
+	<device match="arp" />
+	<device match="bpf" />
+	<device match="conslog" />
+	<device match="cpu/self/cpuid" />
+	<device match="crypto" />
+	<device match="cryptoadm" />
+	<device match="dsk" />
+	<device match="dtrace/*" />
+	<device match="dtrace/provider/*" />
+	<device match="fd" />
+	<device match="ipnet" />
+	<device match="kstat" />
+	<device match="lo0" />
+	<device match="log" />
+	<device match="logindmux" />
+	<device match="nsmb" />
+	<device match="net/*" />
+	<device match="null" />
+	<device match="openprom" arch="sparc" />
+	<device match="poll" />
+	<device match="pool" />
+	<device match="ptmx" />
+	<device match="pts/*" />
+	<device match="random" />
+	<device match="rdsk" />
+	<device match="rmt" />
+	<device match="sad/user" />
+	<device match="svvslo0" />
+	<device match="svvslo1" />
+	<device match="svvslo2" />
+	<device match="svvslo3" />
+	<device match="swap" />
+	<device match="sysevent" />
+	<device match="tcp" />
+	<device match="tcp6" />
+	<device match="term" />
+	<device match="ticlts" />
+	<device match="ticots" />
+	<device match="ticotsord" />
+	<device match="tty" />
+	<device match="udp" />
+	<device match="udp6" />
+	<device match="urandom" />
+	<device match="zero" />
+	<device match="zfs" />
+
+	<!-- Devices to create in exclusive IP zone only -->
+	<device match="dld" ip-type="exclusive" />
+	<device match="icmp" ip-type="exclusive" />
+	<device match="icmp6" ip-type="exclusive" />
+	<device match="ip" ip-type="exclusive" />
+	<device match="ip6" ip-type="exclusive" />
+	<device match="ipauth" ip-type="exclusive" />
+	<device match="ipf" ip-type="exclusive" />
+	<device match="ipl" ip-type="exclusive" />
+	<device match="iplookup" ip-type="exclusive" />
+	<device match="ipmpstub" ip-type="exclusive" />
+	<device match="ipnat" ip-type="exclusive" />
+	<device match="ipscan" ip-type="exclusive" />
+	<device match="ipsecah" ip-type="exclusive" />
+	<device match="ipsecesp" ip-type="exclusive" />
+	<device match="ipstate" ip-type="exclusive" />
+	<device match="ipsync" ip-type="exclusive" />
+	<device match="iptunq" ip-type="exclusive" />
+	<device match="keysock" ip-type="exclusive" />
+	<device match="rawip" ip-type="exclusive" />
+	<device match="rawip6" ip-type="exclusive" />
+	<device match="rts" ip-type="exclusive" />
+	<device match="sad/admin" ip-type="exclusive" />
+	<device match="sctp" ip-type="exclusive" />
+	<device match="sctp6" ip-type="exclusive" />
+	<device match="spdsock" ip-type="exclusive" />
+	<device match="sppp" ip-type="exclusive" />
+	<device match="sppptun" ip-type="exclusive" />
+
+	<!-- Renamed devices to create under /dev -->
+	<device match="zcons/%z/zoneconsole" name="zconsole" />
+
+	<!-- Symlinks to create under /dev -->
+	<symlink source="console" target="zconsole" />
+	<symlink source="dtremote" target="/dev/null" />
+	<symlink source="msglog" target="zconsole" />
+	<symlink source="stderr" target="./fd/2" />
+	<symlink source="stdin" target="./fd/0" />
+	<symlink source="stdout" target="./fd/1" />
+	<symlink source="syscon" target="zconsole" />
+	<symlink source="sysmsg" target="zconsole" />
+	<symlink source="systty" target="zconsole" />
+</platform>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/poststate.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,60 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+# States
+# ZONE_STATE_CONFIGURED           0 (never see)
+# ZONE_STATE_INCOMPLETE           1 (never see)
+# ZONE_STATE_INSTALLED            2
+# ZONE_STATE_READY                3
+# ZONE_STATE_RUNNING              4
+# ZONE_STATE_SHUTTING_DOWN        5
+# ZONE_STATE_DOWN                 6
+# ZONE_STATE_MOUNTED              7
+
+# cmd
+#
+# ready			0
+# boot			1
+# halt			4
+
+zonename=$1
+zonepath=$2
+state=$3
+cmd=$4
+
+# If we're readying the zone, update the zone index file to look like this is
+# the global zone.
+if (( $cmd == 0 )); then
+	echo "global:installed:/" > $zonepath/root/etc/zones/index
+elif (( $cmd == 4 )); then
+	# Leave the active dataset mounted after halting (this might be
+	# a different dataset than what was mounted).
+	mount_active_ds
+fi
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/prestate.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,56 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+# States
+# ZONE_STATE_CONFIGURED           0 (never see)
+# ZONE_STATE_INCOMPLETE           1 (never see)
+# ZONE_STATE_INSTALLED            2
+# ZONE_STATE_READY                3
+# ZONE_STATE_RUNNING              4
+# ZONE_STATE_SHUTTING_DOWN        5
+# ZONE_STATE_DOWN                 6
+# ZONE_STATE_MOUNTED              7
+
+# cmd
+#
+# ready			0
+# boot			1
+# halt			4
+
+zonename=$1
+zonepath=$2
+state=$3
+cmd=$4
+
+# If we're not readying the zone, then just return.
+if (( $cmd == 0 )); then
+	# Mount active dataset on the root.
+	mount_active_ds
+fi
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/s10_boot.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,174 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#    
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#    
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# s10 boot script.
+#
+# The arguments to this script are the zone name and the zonepath.
+#
+
+. /usr/lib/brand/solaris10/common.ksh
+
+ZONENAME=$1
+ZONEPATH=$2
+ZONEROOT=$ZONEPATH/root
+
+arch=`uname -p`
+if [ "$arch" = "i386" ]; then
+	ARCH32=i86
+        ARCH64=amd64
+elif [ "$arch" = "sparc" ]; then
+	# 32-bit SPARC not supported!
+	ARCH32=
+        ARCH64=sparcv9
+else
+        echo "Unsupported architecture: $arch" 
+        exit 2
+fi
+
+#
+# Run the s10_support boot hook.
+#
+/usr/lib/brand/solaris10/s10_support boot $ZONENAME
+if (( $? != 0 )) ; then
+        exit 1
+fi
+
+BRANDDIR=/.SUNWnative/usr/lib/brand/solaris10;
+FILEDIR=$BRANDDIR/files;
+EXIT_CODE=1
+
+#
+# Replace the specified file in the booting zone with a wrapper script that
+# invokes s10_isaexec_wrapper.  This is a convenience function that reduces
+# clutter and code duplication.
+#
+# Parameters:
+#	$1	The full path of the file to replace (e.g., /sbin/ifconfig)
+#	$2	The access mode of the replacement file in hex (e.g., 0555)
+#	$3	The name of the replacement file's owner (e.g., root:bin)
+#
+# NOTE: The checks performed in the 'if' statement below are not generic: they
+# depend on the success of the zone filesystem structure validation performed
+# above to ensure that intermediate directories exist and aren't symlinks.
+#
+replace_with_native() {
+	path_dname=$ZONEROOT/`dirname $1`
+	if [ ! -h $path_dname -a -d $path_dname ]; then
+		safe_replace $ZONEROOT/$1 $BRANDDIR/s10_isaexec_wrapper $2 $3 \
+		    remove
+	fi
+}
+
+#
+# Before we boot we validate and fix, if necessary, the required files within
+# the zone.  These modifications can be lost if a patch is applied within the
+# zone, so we validate and fix the zone every time it boots.
+#
+
+#
+# BINARY REPLACEMENT
+#
+# This section of the boot script is responsible for replacing Solaris 10
+# binaries within the booting zone with Nevada binaries.  This is a two-step
+# process: First, the directory structure of the zone is validated to ensure
+# that binary replacement will proceed safely.  Second, Solaris 10 binaries
+# are replaced with Nevada binaries.
+#
+# Here's an example.  Suppose that you want to replace /usr/bin/zcat with the
+# Nevada /usr/bin/zcat binary.  Then you should do the following:
+#
+#	1.  Go to the section below labeled "STEP ONE" and add the following
+#	    two lines:
+#
+#		safe_dir /usr
+#		safe_dir /usr/bin
+#
+#	    These lines ensure that both /usr and /usr/bin are directories
+#	    within the booting zone that can be safely accessed by the global
+#	    zone.
+#	2.  Go to the section below labeled "STEP TWO" and add the following
+#	    line:
+#
+#		replace_with_native /usr/bin/zcat 0555 root:bin
+#
+# Details about the binary replacement procedure can be found in the Solaris 10
+# Containers Developer Guide.
+#
+
+#
+# STEP ONE
+#
+# Validate that the zone filesystem looks like we expect it to.
+#
+safe_dir /usr
+safe_dir /usr/lib
+safe_dir /usr/bin
+safe_dir /usr/sbin
+safe_dir /sbin
+
+#
+# STEP TWO
+#
+# Replace Solaris 10 binaries with Nevada binaries.
+#
+
+#
+# Replace various network-related programs with native wrappers.
+#
+replace_with_native /sbin/ifconfig 0555 root:bin
+
+#
+# Replace automount and automountd with native wrappers.
+#
+if [ ! -h $ZONEROOT/usr/lib/fs/autofs -a -d $ZONEROOT/usr/lib/fs/autofs ]; then
+	safe_replace $ZONEROOT/usr/lib/fs/autofs/automount \
+	    $BRANDDIR/s10_automount 0555 root:bin remove
+fi
+if [ ! -h $ZONEROOT/usr/lib/autofs -a -d $ZONEROOT/usr/lib/autofs ]; then
+	safe_replace $ZONEROOT/usr/lib/autofs/automountd \
+	    $BRANDDIR/s10_automountd 0555 root:bin remove
+fi
+
+#
+# END OF STEP TWO
+#
+
+#
+# Replace add_drv and rem_drv with /usr/bin/true so that pkgs/patches which
+# install or remove drivers will work.  NOTE: add_drv and rem_drv are hard
+# linked to isaexec so we want to remove the current executable and
+# then copy true so that we don't clobber isaexec.
+#
+filename=$ZONEROOT/usr/sbin/add_drv
+[ ! -f $filename.pre_p2v ] && safe_backup $filename $filename.pre_p2v
+rm -f $filename
+safe_copy $ZONEROOT/usr/bin/true $filename
+
+filename=$ZONEROOT/usr/sbin/rem_drv
+[ ! -f $filename.pre_p2v ] && safe_backup $filename $filename.pre_p2v
+rm -f $filename
+safe_copy $ZONEROOT/usr/bin/true $filename
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/smf_disable.conf	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,28 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SMF services which should be disabled when installing
+# the zone.  Site-specific services which must be disabled should be listed
+# in this file.  During the zone installation, the services will be disabled
+# if they existed on the original physical system.
+# 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/smf_disable.lst	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SMF services which should be disabled when installing
+# the zone.  Do not edit this file.  Site-specific services which must be
+# disabled should be listed in the /etc/brand/solaris10/smf_disable.conf
+# file.  During the zone installation, the services will be disabled if
+# they existed on the original physical system.
+# 
+svc:/network/smb/server
+svc:/system/virtualbox/vboxservice
+svc:/ldoms/ldmd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/uninstall.ksh	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,133 @@
+#!/bin/ksh93 -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# common shell script functions
+#
+. /usr/lib/brand/solaris10/common.ksh
+. /usr/lib/brand/shared/uninstall.ksh
+
+#
+# options processing
+#
+zonename=$1
+if [ -z "$zonename" ]; then
+	printf "$f_abort\n" >&2
+	exit $ZONE_SUBPROC_FATAL
+fi
+zonepath=$2
+if [ -z "$zonepath" ]; then
+	printf "$f_abort" >&2
+	exit $ZONE_SUBPROC_FATAL
+fi
+shift 2
+
+options="FhHnv"
+options_repeat=""
+options_seen=""
+
+opt_F=""
+opt_n=""
+opt_v=""
+
+# check for bad or duplicate options
+OPTIND=1
+while getopts $options OPT ; do
+case $OPT in
+	\? ) usage_err ;; # invalid argument
+	: ) usage_err ;; # argument expected
+	* )
+		opt=`echo $OPT | sed 's/-\+//'`
+		if [ -n "$options_repeat" ]; then
+			echo $options_repeat | grep $opt >/dev/null
+			[ $? = 0 ] && break
+		fi
+		( echo $options_seen | grep $opt >/dev/null ) &&
+			usage_err
+		options_seen="${options_seen}${opt}"
+		;;
+esac
+done
+
+# check for a help request
+OPTIND=1
+while getopts :$options OPT ; do
+case $OPT in
+	h|H ) usage
+esac
+done
+
+# process options
+OPTIND=1
+while getopts :$options OPT ; do
+case $OPT in
+	F ) opt_F="-F" ;;
+	n ) opt_n="-n" ;;
+	v ) opt_v="-v" ;;
+esac
+done
+shift `expr $OPTIND - 1`
+
+[ $# -gt 0 ]  && usage_err
+
+#
+# main
+#
+zoneroot=$zonepath/root
+
+nop=""
+if [[ -n "$opt_n" ]]; then
+	nop="echo"
+	#
+	# in '-n' mode we should never return success (since we haven't
+	# actually done anything). so override ZONE_SUBPROC_OK here.
+	#
+	ZONE_SUBPROC_OK=$ZONE_SUBPROC_FATAL
+fi
+
+#
+# We want uninstall to work in the face of various problems, such as a
+# zone with no delegated root dataset or multiple active datasets, so we
+# don't use the common functions.  Instead, we do our own work and
+# are tolerant of errors.
+#
+uninstall_get_zonepath_ds
+uninstall_get_zonepath_root_ds
+
+# find all the zone BE datasets.
+unset fs_all
+(( fs_all_c = 0 ))
+/sbin/zfs list -H -t filesystem -o name -r $ZONEPATH_RDS | while read fs; do
+	# only look at filesystems directly below $ZONEPATH_RDS
+	[[ "$fs" != ~()($ZONEPATH_RDS/+([^/])) ]] && continue
+
+	fs_all[$fs_all_c]=$fs
+	(( fs_all_c = $fs_all_c + 1 ))
+done
+
+destroy_zone_datasets
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/zone/version	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This is the current latest version of the solaris10 brand emulation.  The
+# version should be incremented if new capabilities are added to the
+# emulation for new features backported to S10.  The S10 required emulation
+# version should also be incremented so that the enhanced version of S10
+# won't be usable in an older version of the solaris10 brand.
+#
+0
--- a/usr/src/pkgdefs/Makefile	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/pkgdefs/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -439,6 +439,8 @@
 	SUNWrsm	\
 	SUNWrsmo \
 	SUNWrtls \
+	SUNWs10brandr \
+	SUNWs10brandu \
 	SUNWsacom \
 	SUNWsasnm \
 	SUNWsbp2 \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+all: $(FILES) depend
+install: all pkg    
+
+include ../Makefile.targ
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/depend	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWcakr	Core Solaris Kernel Architecture (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWckr	Core Solaris Kernel (Root)
+P SUNWcnetr	Core Solaris Network Infrastructure (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries
+P SUNWzoneu	Solaris Zones (Usr)
+P SUNWzoner	Solaris Zones (Root)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/pkginfo.tmpl	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWs10brandr"
+NAME="Solaris 10 Containers: solaris10 brand support (Root)"
+BASEDIR=/
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+CATEGORY="system"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+DESC="Support for the 'Solaris10' Brand"
+VENDOR="Sun Microsystems, Inc."
+EMAIL=
+SUNW_PKGVERS=1.0
+CLASSES="none preserve"
+MAXINST="1000"
+HOTLINE="Please contact your local service provider"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_com	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# Solaris 10 Brand
+#
+
+i pkginfo
+i copyright
+i depend
+
+# solaris10 brand template
+d none etc 755 root sys
+d none etc/brand 755 root sys
+d none etc/brand/solaris10 755 root sys
+e preserve etc/brand/solaris10/pkgrm.conf 644 root sys
+e preserve etc/brand/solaris10/smf_disable.conf 644 root sys
+d none etc/zones 755 root sys
+f none etc/zones/SUNWsolaris10.xml 444 root bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_i386	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# Solaris 10 Brand
+#
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_sparc	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# Solaris 10 Brand
+#
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+
+# The kernel brand module
+# Normally, brand modules are delivered via /usr/kernel because they are not
+# required for boot.  However, the solars10 brand syscall emulation module must
+# be delivered via /platform on SPARC because it depends on platform-specific
+# kernel data structures (specifically the machcpu_t) and we don't currently
+# support loading platform-specific kernel modules from /usr/platform.
+#
+d none platform 0755 root sys
+d none platform/sun4u 0755 root sys
+d none platform/sun4u/kernel 0755 root sys
+d none platform/sun4u/kernel/brand 0755 root sys
+d none platform/sun4u/kernel/brand/sparcv9 0755 root sys
+f none platform/sun4u/kernel/brand/sparcv9/s10_brand 0755 root sys
+d none platform/sun4v 0755 root sys
+d none platform/sun4v/kernel 0755 root sys
+d none platform/sun4v/kernel/brand 0755 root sys
+d none platform/sun4v/kernel/brand/sparcv9 0755 root sys
+f none platform/sun4v/kernel/brand/sparcv9/s10_brand 0755 root sys
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+all: $(FILES) depend
+install: all pkg    
+
+include ../Makefile.targ
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/depend	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWcakr	Core Solaris Kernel Architecture (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWckr	Core Solaris Kernel (Root)
+P SUNWcnetr	Core Solaris Network Infrastructure (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries
+P SUNWzoneu	Solaris Zones (Usr)
+P SUNWzoner	Solaris Zones (Root)
+P SUNWs10brandr	Solaris 10 Brand (Root)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/pkginfo.tmpl	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWs10brandu"
+NAME="Solaris 10 Containers: solaris10 brand support (Usr)"
+BASEDIR=/
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+CATEGORY="system"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+DESC="Support for the 'solaris10' Brand"
+VENDOR="Sun Microsystems, Inc."
+EMAIL=
+SUNW_PKGVERS=1.0
+CLASSES="none"
+MAXINST="1000"
+HOTLINE="Please contact your local service provider"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_com	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+i pkginfo
+i copyright
+i depend
+
+d none usr 755 root sys
+d none usr/lib 755 root bin
+f none usr/lib/s10_brand.so.1 0755 root bin
+f none usr/lib/s10_npreload.so.1 0755 root bin
+d none usr/lib/brand 755 root bin
+d none usr/lib/brand/solaris10 755 root sys
+f none usr/lib/brand/solaris10/attach 755 root bin
+f none usr/lib/brand/solaris10/clone 755 root bin
+f none usr/lib/brand/solaris10/common.ksh 444 root bin
+f none usr/lib/brand/solaris10/config.xml 444 root bin
+f none usr/lib/brand/solaris10/detach 755 root bin
+f none usr/lib/brand/solaris10/image_install 755 root bin
+f none usr/lib/brand/solaris10/p2v 755 root bin
+f none usr/lib/brand/solaris10/pkgrm.lst 444 root bin
+f none usr/lib/brand/solaris10/platform.xml 444 root bin
+f none usr/lib/brand/solaris10/poststate 755 root bin
+f none usr/lib/brand/solaris10/prestate 755 root bin
+f none usr/lib/brand/solaris10/s10_automount 755 root bin
+f none usr/lib/brand/solaris10/s10_automountd 755 root bin
+f none usr/lib/brand/solaris10/s10_boot 755 root bin
+f none usr/lib/brand/solaris10/s10_native 755 root bin
+f none usr/lib/brand/solaris10/s10_isaexec_wrapper 755 root bin
+f none usr/lib/brand/solaris10/s10_support 755 root bin
+f none usr/lib/brand/solaris10/solaris10_librtld_db.so.1 755 root bin
+f none usr/lib/brand/solaris10/smf_disable.lst 444 root bin
+f none usr/lib/brand/solaris10/uninstall 755 root bin
+f none usr/lib/brand/solaris10/version 444 root bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_i386	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# Solaris 10 Brand
+#
+
+!include prototype_com
+
+# the kernel brand module
+d none usr/kernel 0755 root sys
+d none usr/kernel/brand 0755 root sys
+f none usr/kernel/brand/s10_brand 0755 root sys
+d none usr/kernel/brand/amd64 0755 root sys
+f none usr/kernel/brand/amd64/s10_brand 0755 root sys
+
+# The user library
+d none usr/lib/amd64 0755 root bin
+f none usr/lib/amd64/s10_brand.so.1 0755 root bin
+f none usr/lib/amd64/s10_npreload.so.1 0755 root bin
+d none usr/lib/brand/solaris10/amd64 755 root bin
+s none usr/lib/brand/solaris10/64=amd64 755 root bin
+f none usr/lib/brand/solaris10/amd64/solaris10_librtld_db.so.1 755 root bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_sparc	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# Solaris 10 Brand
+#
+
+!include prototype_com
+
+# The user library
+d none usr/lib/brand/solaris10/sparcv9 755 root bin
+s none usr/lib/brand/solaris10/64=sparcv9 755 root bin
+f none usr/lib/brand/solaris10/sparcv9/solaris10_librtld_db.so.1 755 root bin
+d none usr/lib/sparcv9 0755 root bin
+f none usr/lib/sparcv9/s10_brand.so.1 0755 root bin
+f none usr/lib/sparcv9/s10_npreload.so.1 0755 root bin
--- a/usr/src/pkgdefs/SUNWzoneu/prototype_com	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/pkgdefs/SUNWzoneu/prototype_com	Thu Oct 22 11:21:27 2009 -0700
@@ -60,6 +60,8 @@
 f none usr/lib/brand/native/sw_support 755 root bin
 d none usr/lib/brand/shared 755 root sys
 f none usr/lib/brand/shared/common.ksh 444 root bin
+f none usr/lib/brand/shared/query 755 root bin
+f none usr/lib/brand/shared/uninstall.ksh 444 root bin
 f none usr/lib/libbrand.so.1 755 root bin
 f none usr/lib/libzonecfg.so.1 755 root bin
 d none usr/lib/zones 755 root bin
--- a/usr/src/uts/common/Makefile.rules	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/common/Makefile.rules	Thu Oct 22 11:21:27 2009 -0700
@@ -100,6 +100,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/common/brand/solaris10/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/common/c2/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1525,6 +1529,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/brand/sn1/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/common/brand/solaris10/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/c2/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- a/usr/src/uts/common/brand/sn1/sn1_brand.c	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/common/brand/sn1/sn1_brand.c	Thu Oct 22 11:21:27 2009 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -604,20 +604,22 @@
 			 * calculated address from above.
 			 */
 			sedp->sed_ldentry = sedp->sed_entry;
+			sedp->sed_entry = NULL;
+			sedp->sed_phdr = NULL;
+			sedp->sed_phent = NULL;
+			sedp->sed_phnum = NULL;
 			sedp->sed_lddata = NULL;
-			sedp->sed_base = NULL;
-		}
-	}
+			sedp->sed_base = voffset;
 
-	if (uphdr_vaddr != (Addr)-1) {
-		if (ehdr.e_type == ET_DYN) {
-			/*
-			 * Delay setting the brkbase until the first call to
-			 * brk(); see elfexec() for details.
-			 */
-			env.ex_bssbase = (caddr_t)0;
-			env.ex_brkbase = (caddr_t)0;
-			env.ex_brksize = 0;
+			if (ehdr.e_type == ET_DYN) {
+				/*
+				 * Delay setting the brkbase until the first
+				 * call to brk(); see elfexec() for details.
+				 */
+				env.ex_bssbase = (caddr_t)0;
+				env.ex_brkbase = (caddr_t)0;
+				env.ex_brksize = 0;
+			}
 		}
 	}
 
@@ -706,42 +708,38 @@
 	 * linker.
 	 */
 	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
+		ulong_t val;
+
 		switch (up->u_auxv[i].a_type) {
 		case AT_SUN_BRAND_SN1_LDDATA:
 			up->u_auxv[i].a_un.a_val = sed.sed_lddata;
-			break;
+			continue;
 		case AT_BASE:
-			if (sedp->sed_base == NULL) {
-				/* Hide base for static binaries */
-				up->u_auxv[i].a_type = AT_IGNORE;
-				up->u_auxv[i].a_un.a_val = NULL;
-			} else {
-				up->u_auxv[i].a_un.a_val = sedp->sed_base;
-			}
+			val = sedp->sed_base;
 			break;
 		case AT_ENTRY:
-			up->u_auxv[i].a_un.a_val = sedp->sed_entry;
+			val = sedp->sed_entry;
 			break;
 		case AT_PHDR:
-			up->u_auxv[i].a_un.a_val = sedp->sed_phdr;
+			val = sedp->sed_phdr;
 			break;
 		case AT_PHENT:
-			up->u_auxv[i].a_un.a_val = sedp->sed_phent;
+			val = sedp->sed_phent;
 			break;
 		case AT_PHNUM:
-			up->u_auxv[i].a_un.a_val = sedp->sed_phnum;
+			val = sedp->sed_phnum;
 			break;
 		case AT_SUN_LDDATA:
-			if (sedp->sed_lddata == NULL) {
-				/* Hide lddata for static binaries */
-				up->u_auxv[i].a_type = AT_IGNORE;
-				up->u_auxv[i].a_un.a_val = NULL;
-			} else {
-				up->u_auxv[i].a_un.a_val = sedp->sed_lddata;
-			}
+			val = sedp->sed_lddata;
 			break;
 		default:
-			break;
+			continue;
+		}
+
+		up->u_auxv[i].a_un.a_val = val;
+		if (val == NULL) {
+			/* Hide the entry for static binaries */
+			up->u_auxv[i].a_type = AT_IGNORE;
 		}
 	}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/brand/solaris10/s10_brand.c	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,1019 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/errno.h>
+#include <sys/exec.h>
+#include <sys/kmem.h>
+#include <sys/modctl.h>
+#include <sys/model.h>
+#include <sys/proc.h>
+#include <sys/syscall.h>
+#include <sys/systm.h>
+#include <sys/thread.h>
+#include <sys/cmn_err.h>
+#include <sys/archsystm.h>
+#include <sys/pathname.h>
+#include <sys/sunddi.h>
+
+#include <sys/machbrand.h>
+#include <sys/brand.h>
+#include "s10_brand.h"
+
+char *s10_emulation_table = NULL;
+
+void	s10_init_brand_data(zone_t *);
+void	s10_free_brand_data(zone_t *);
+void	s10_setbrand(proc_t *);
+int	s10_getattr(zone_t *, int, void *, size_t *);
+int	s10_setattr(zone_t *, int, void *, size_t);
+int	s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
+		uintptr_t, uintptr_t, uintptr_t);
+void	s10_copy_procdata(proc_t *, proc_t *);
+void	s10_proc_exit(struct proc *, klwp_t *);
+void	s10_exec();
+int	s10_initlwp(klwp_t *);
+void	s10_forklwp(klwp_t *, klwp_t *);
+void	s10_freelwp(klwp_t *);
+void	s10_lwpexit(klwp_t *);
+int	s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
+	long *, int, caddr_t, cred_t *, int);
+
+/* s10 brand */
+struct brand_ops s10_brops = {
+	s10_init_brand_data,
+	s10_free_brand_data,
+	s10_brandsys,
+	s10_setbrand,
+	s10_getattr,
+	s10_setattr,
+	s10_copy_procdata,
+	s10_proc_exit,
+	s10_exec,
+	lwp_setrval,
+	s10_initlwp,
+	s10_forklwp,
+	s10_freelwp,
+	s10_lwpexit,
+	s10_elfexec
+};
+
+#ifdef	sparc
+
+struct brand_mach_ops s10_mops = {
+	s10_brand_syscall_callback,
+	s10_brand_syscall32_callback
+};
+
+#else	/* sparc */
+
+#ifdef	__amd64
+
+struct brand_mach_ops s10_mops = {
+	s10_brand_sysenter_callback,
+	NULL,
+	s10_brand_int91_callback,
+	s10_brand_syscall_callback,
+	s10_brand_syscall32_callback,
+	NULL
+};
+
+#else	/* ! __amd64 */
+
+struct brand_mach_ops s10_mops = {
+	s10_brand_sysenter_callback,
+	NULL,
+	NULL,
+	s10_brand_syscall_callback,
+	NULL,
+	NULL
+};
+#endif	/* __amd64 */
+
+#endif	/* _sparc */
+
+struct brand	s10_brand = {
+	BRAND_VER_1,
+	"solaris10",
+	&s10_brops,
+	&s10_mops
+};
+
+static struct modlbrand modlbrand = {
+	&mod_brandops,		/* type of module */
+	"Solaris 10 Brand",	/* description of module */
+	&s10_brand		/* driver ops */
+};
+
+static struct modlinkage modlinkage = {
+	MODREV_1, (void *)&modlbrand, NULL
+};
+
+void
+s10_setbrand(proc_t *p)
+{
+	ASSERT(p->p_brand == &s10_brand);
+	ASSERT(p->p_brand_data == NULL);
+
+	/*
+	 * We should only be called from exec(), when we know the process
+	 * is single-threaded.
+	 */
+	ASSERT(p->p_tlist == p->p_tlist->t_forw);
+
+	p->p_brand_data = kmem_zalloc(sizeof (s10_proc_data_t), KM_SLEEP);
+	(void) s10_initlwp(p->p_tlist->t_lwp);
+}
+
+int
+s10_get_zone_emul_version(zone_t *zone)
+{
+	return (((s10_zone_data_t *)
+	    zone->zone_brand_data)->s10zd_emul_version);
+}
+
+int
+s10_get_emul_version()
+{
+	return (s10_get_zone_emul_version(curzone));
+}
+
+void
+s10_set_emul_version(zone_t *zone, int vers)
+{
+	s10_zone_data_t *s10zd = (s10_zone_data_t *)zone->zone_brand_data;
+	s10zd->s10zd_emul_version = vers;
+}
+
+/*ARGSUSED*/
+int
+s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
+{
+	int num;
+
+	ASSERT(zone->zone_brand == &s10_brand);
+	if (attr == S10_EMUL_VERSION_NUM) {
+		if (*bufsize < sizeof (int))
+			return (ERANGE);
+		num = s10_get_emul_version();
+		if (copyout(&num, buf, sizeof (int)) != 0)
+			return (EFAULT);
+		*bufsize = sizeof (int);
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+int
+s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
+{
+	int num;
+
+	ASSERT(zone->zone_brand == &s10_brand);
+	if (attr == S10_EMUL_VERSION_NUM) {
+		if (bufsize > sizeof (int))
+			return (ERANGE);
+		if (copyin(buf, &num, sizeof (num)) != 0)
+			return (EFAULT);
+		s10_set_emul_version(zone, num);
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+#ifdef	__amd64
+/*
+ * The Nevada kernel clears %fs for threads in 64-bit x86 processes but S10's
+ * libc expects %fs to be nonzero.  This causes some committed
+ * libc/libthread interfaces (e.g., thr_main()) to fail, which impacts several
+ * libraries, including libdoor.  This function sets the specified LWP's %fs
+ * register to the legacy S10 selector value (LWPFS_SEL).
+ *
+ * The best solution to the aforementioned problem is backporting CRs
+ * 6467491 to Solaris 10 so that 64-bit x86 Solaris 10 processes
+ * would accept zero for %fs.  Backporting the CRs is a requirement for running
+ * S10 Containers in PV domUs because 64-bit Xen clears %fsbase when %fs is
+ * nonzero.  Such behavior breaks 64-bit processes because Xen has to fetch the
+ * FS segments' base addresses from the LWPs' GDTs, which are only capable of
+ * 32-bit addressing.
+ */
+/*ARGSUSED*/
+static void
+s10_amd64_correct_fsreg(klwp_t *l)
+{
+	if (lwp_getdatamodel(l) == DATAMODEL_NATIVE) {
+		kpreempt_disable();
+		l->lwp_pcb.pcb_fs = LWPFS_SEL;
+		l->lwp_pcb.pcb_rupdate = 1;
+		lwptot(l)->t_post_sys = 1;	/* Guarantee update_sregs() */
+		kpreempt_enable();
+	}
+}
+#endif	/* __amd64 */
+
+int
+s10_native()
+{
+	struct user	*up = PTOU(curproc);
+	char		*args_new, *comm_new, *p;
+	int		len;
+
+	len = sizeof (S10_NATIVE_LINKER32 " ") - 1;
+
+	/*
+	 * Make sure that the process' interpreter is the native dynamic linker.
+	 * Convention dictates that native processes executing within solaris10-
+	 * branded zones are interpreted by the native dynamic linker (the
+	 * process and its arguments are specified as arguments to the dynamic
+	 * linker).  If this convention is violated (i.e.,
+	 * brandsys(B_S10_NATIVE, ...) is invoked by a process that shouldn't be
+	 * native), then do nothing and silently indicate success.
+	 */
+	if (strcmp(up->u_comm, S10_LINKER_NAME) != 0)
+		return (0);
+	if (strncmp(up->u_psargs, S10_NATIVE_LINKER64 " /", len + 4) == 0)
+		len += 3;		/* to account for "/64" in the path */
+	else if (strncmp(up->u_psargs, S10_NATIVE_LINKER32 " /", len + 1) != 0)
+		return (0);
+
+	args_new = strdup(&up->u_psargs[len]);
+	if ((p = strchr(args_new, ' ')) != NULL)
+		*p = '\0';
+	if ((comm_new = strrchr(args_new, '/')) != NULL)
+		comm_new = strdup(comm_new + 1);
+	else
+		comm_new = strdup(args_new);
+	if (p != NULL)
+		*p = ' ';
+
+	if ((strlen(args_new) != 0) && (strlen(comm_new) != 0)) {
+		mutex_enter(&curproc->p_lock);
+		(void) strlcpy(up->u_comm, comm_new, MAXCOMLEN+1);
+		(void) strlcpy(up->u_psargs, args_new, PSARGSZ);
+		mutex_exit(&curproc->p_lock);
+	}
+
+	strfree(args_new);
+	strfree(comm_new);
+	return (0);
+}
+
+/*
+ * Get the address of the user-space system call handler from the user
+ * process and attach it to the proc structure.
+ */
+/*ARGSUSED*/
+int
+s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
+    uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
+{
+	s10_proc_data_t	*spd;
+	s10_brand_reg_t	reg;
+	proc_t		*p = curproc;
+	int		err;
+
+	*rval = 0;
+
+	/*
+	 * B_EXEC_BRAND is redundant
+	 * since the kernel assumes a native process doing an exec
+	 * in a branded zone is going to run a branded processes.
+	 * hence we don't support this operation.
+	 */
+	if (cmd == B_EXEC_BRAND)
+		return (ENOSYS);
+
+	if (cmd == B_S10_NATIVE)
+		return (s10_native());
+
+	/* For all other operations this must be a branded process. */
+	if (p->p_brand == &native_brand)
+		return (ENOSYS);
+
+	ASSERT(p->p_brand == &s10_brand);
+	ASSERT(p->p_brand_data != NULL);
+
+	spd = (s10_proc_data_t *)p->p_brand_data;
+
+	switch (cmd) {
+	case B_EXEC_NATIVE:
+		err = exec_common(
+		    (char *)arg1, (const char **)arg2, (const char **)arg3,
+		    EBA_NATIVE);
+		return (err);
+
+	case B_REGISTER:
+		if (p->p_model == DATAMODEL_NATIVE) {
+			if (copyin((void *)arg1, &reg, sizeof (reg)) != 0)
+				return (EFAULT);
+#if defined(_LP64)
+		} else {
+			s10_brand_reg32_t reg32;
+
+			if (copyin((void *)arg1, &reg32, sizeof (reg32)) != 0)
+				return (EFAULT);
+			reg.sbr_version = reg32.sbr_version;
+			reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
+#endif /* _LP64 */
+		}
+
+		if (reg.sbr_version != S10_VERSION)
+			return (ENOTSUP);
+		spd->spd_handler = reg.sbr_handler;
+		return (0);
+
+	case B_ELFDATA:
+		if (p->p_model == DATAMODEL_NATIVE) {
+			if (copyout(&spd->spd_elf_data, (void *)arg1,
+			    sizeof (s10_elf_data_t)) != 0)
+				return (EFAULT);
+#if defined(_LP64)
+		} else {
+			s10_elf_data32_t sed32;
+
+			sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
+			sed32.sed_phent = spd->spd_elf_data.sed_phent;
+			sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
+			sed32.sed_entry = spd->spd_elf_data.sed_entry;
+			sed32.sed_base = spd->spd_elf_data.sed_base;
+			sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
+			sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
+			if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0)
+				return (EFAULT);
+#endif /* _LP64 */
+		}
+		return (0);
+
+	case B_S10_PIDINFO:
+		/*
+		 * The s10 brand needs to be able to get the pid of the
+		 * current process and the pid of the zone's init, and it
+		 * needs to do this on every process startup.  Early in
+		 * brand startup, we can't call getpid() because calls to
+		 * getpid() represent a magical signal to some old-skool
+		 * debuggers.  By merging all of this into one call, we
+		 * make this quite a bit cheaper and easier to handle in
+		 * the brand module.
+		 */
+		if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0)
+			return (EFAULT);
+		if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2,
+		    sizeof (pid_t)) != 0)
+			return (EFAULT);
+		return (0);
+
+	case B_S10_TRUSS_POINT:
+		/*
+		 * This subcommand exists so that we can see truss output
+		 * from interposed system calls that return without first
+		 * calling any other system call, meaning they would be
+		 * invisible to truss(1).
+		 *
+		 * If the second argument is set non-zero, set errno to that
+		 * value as well.
+		 *
+		 * Arguments are:
+		 *
+		 *    arg1: syscall number
+		 *    arg2: errno
+		 */
+		return ((arg2 == 0) ? 0 : set_errno((uint_t)arg2));
+
+#ifdef	__amd64
+	case B_S10_FSREGCORRECTION:
+		/*
+		 * This subcommand exists so that the SYS_lwp_private and
+		 * SYS_lwp_create syscalls can manually set the current thread's
+		 * %fs register to the legacy S10 selector value for 64-bit x86
+		 * processes.
+		 */
+		s10_amd64_correct_fsreg(ttolwp(curthread));
+		return (0);
+#endif	/* __amd64 */
+	}
+
+	return (EINVAL);
+}
+
+/*
+ * Copy the per-process brand data from a parent proc to a child.
+ */
+void
+s10_copy_procdata(proc_t *child, proc_t *parent)
+{
+	s10_proc_data_t	*spd;
+
+	ASSERT(parent->p_brand == &s10_brand);
+	ASSERT(child->p_brand == &s10_brand);
+	ASSERT(parent->p_brand_data != NULL);
+	ASSERT(child->p_brand_data == NULL);
+
+	/* Just duplicate all the proc data of the parent for the child */
+	spd = kmem_alloc(sizeof (s10_proc_data_t), KM_SLEEP);
+	bcopy(parent->p_brand_data, spd, sizeof (s10_proc_data_t));
+	child->p_brand_data = spd;
+}
+
+/*ARGSUSED*/
+void
+s10_proc_exit(struct proc *p, klwp_t *l)
+{
+	ASSERT(p->p_brand == &s10_brand);
+	ASSERT(p->p_brand_data != NULL);
+
+	/*
+	 * We should only be called from proc_exit(), when we know that
+	 * process is single-threaded.
+	 */
+	ASSERT(p->p_tlist == p->p_tlist->t_forw);
+
+	/* upon exit, free our lwp brand data */
+	(void) s10_freelwp(ttolwp(curthread));
+
+	/* upon exit, free our proc brand data */
+	kmem_free(p->p_brand_data, sizeof (s10_proc_data_t));
+	p->p_brand_data = NULL;
+}
+
+void
+s10_exec()
+{
+	s10_proc_data_t	*spd = curproc->p_brand_data;
+
+	ASSERT(curproc->p_brand == &s10_brand);
+	ASSERT(curproc->p_brand_data != NULL);
+	ASSERT(ttolwp(curthread)->lwp_brand != NULL);
+
+	/*
+	 * We should only be called from exec(), when we know the process
+	 * is single-threaded.
+	 */
+	ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
+
+	/* Upon exec, reset our lwp brand data. */
+	(void) s10_freelwp(ttolwp(curthread));
+	(void) s10_initlwp(ttolwp(curthread));
+
+	/*
+	 * Upon exec, reset all the proc brand data, except for the elf
+	 * data associated with the executable we are exec'ing.
+	 */
+	spd->spd_handler = NULL;
+}
+
+/*ARGSUSED*/
+int
+s10_initlwp(klwp_t *l)
+{
+	ASSERT(l->lwp_procp->p_brand == &s10_brand);
+	ASSERT(l->lwp_procp->p_brand_data != NULL);
+	ASSERT(l->lwp_brand == NULL);
+	l->lwp_brand = (void *)-1;
+	return (0);
+}
+
+/*ARGSUSED*/
+void
+s10_forklwp(klwp_t *p, klwp_t *c)
+{
+	ASSERT(p->lwp_procp->p_brand == &s10_brand);
+	ASSERT(c->lwp_procp->p_brand == &s10_brand);
+
+	ASSERT(p->lwp_procp->p_brand_data != NULL);
+	ASSERT(c->lwp_procp->p_brand_data != NULL);
+
+	/* Both LWPs have already had been initialized via s10_initlwp() */
+	ASSERT(p->lwp_brand != NULL);
+	ASSERT(c->lwp_brand != NULL);
+
+#ifdef	__amd64
+	/*
+	 * Only correct the child's %fs register if the parent's %fs register
+	 * is LWPFS_SEL.  If the parent's %fs register is zero, then the Solaris
+	 * 10 environment that we're emulating uses a version of libc that
+	 * works when %fs is zero (i.e., it contains backports of CRs 6467491
+	 * and 6501650).
+	 */
+	if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
+		s10_amd64_correct_fsreg(c);
+#endif	/* __amd64 */
+}
+
+/*ARGSUSED*/
+void
+s10_freelwp(klwp_t *l)
+{
+	ASSERT(l->lwp_procp->p_brand == &s10_brand);
+	ASSERT(l->lwp_procp->p_brand_data != NULL);
+	ASSERT(l->lwp_brand != NULL);
+	l->lwp_brand = NULL;
+}
+
+/*ARGSUSED*/
+void
+s10_lwpexit(klwp_t *l)
+{
+	proc_t	*p = l->lwp_procp;
+
+	ASSERT(l->lwp_procp->p_brand == &s10_brand);
+	ASSERT(l->lwp_procp->p_brand_data != NULL);
+	ASSERT(l->lwp_brand != NULL);
+
+	/*
+	 * We should never be called for the last thread in a process.
+	 * (That case is handled by s10_proc_exit().)  There for this lwp
+	 * must be exiting from a multi-threaded process.
+	 */
+	ASSERT(p->p_tlist != p->p_tlist->t_forw);
+
+	l->lwp_brand = NULL;
+}
+
+void
+s10_free_brand_data(zone_t *zone)
+{
+	kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
+}
+
+void
+s10_init_brand_data(zone_t *zone)
+{
+	s10_zone_data_t *data;
+	ASSERT(zone->zone_brand == &s10_brand);
+	ASSERT(zone->zone_brand_data == NULL);
+	data = (s10_zone_data_t *)kmem_zalloc(sizeof (s10_zone_data_t),
+	    KM_SLEEP);
+	/*
+	 * Initialize the default s10zd_emul_version to S10_EMUL_UNDEF.
+	 * This can be changed by a call to setattr() during zone boot.
+	 */
+	data->s10zd_emul_version = S10_EMUL_UNDEF;
+	zone->zone_brand_data = data;
+}
+
+#if defined(_LP64)
+static void
+Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst)
+{
+	bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
+	dst->e_type =		src->e_type;
+	dst->e_machine =	src->e_machine;
+	dst->e_version =	src->e_version;
+	dst->e_entry =		src->e_entry;
+	dst->e_phoff =		src->e_phoff;
+	dst->e_shoff =		src->e_shoff;
+	dst->e_flags =		src->e_flags;
+	dst->e_ehsize =		src->e_ehsize;
+	dst->e_phentsize =	src->e_phentsize;
+	dst->e_phnum =		src->e_phnum;
+	dst->e_shentsize =	src->e_shentsize;
+	dst->e_shnum =		src->e_shnum;
+	dst->e_shstrndx =	src->e_shstrndx;
+}
+#endif /* _LP64 */
+
+int
+s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
+	int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
+	int brand_action)
+{
+	vnode_t		*nvp;
+	Ehdr		ehdr;
+	Addr		uphdr_vaddr;
+	intptr_t	voffset;
+	int		interp;
+	int		i, err;
+	struct execenv	env;
+	struct user	*up = PTOU(curproc);
+	s10_proc_data_t	*spd;
+	s10_elf_data_t	sed, *sedp;
+	char		*linker;
+	uintptr_t	lddata; /* lddata of executable's linker */
+
+	ASSERT(curproc->p_brand == &s10_brand);
+	ASSERT(curproc->p_brand_data != NULL);
+
+	spd = (s10_proc_data_t *)curproc->p_brand_data;
+	sedp = &spd->spd_elf_data;
+
+	args->brandname = S10_BRANDNAME;
+
+	/*
+	 * We will exec the brand library and then map in the target
+	 * application and (optionally) the brand's default linker.
+	 */
+	if (args->to_model == DATAMODEL_NATIVE) {
+		args->emulator = S10_LIB;
+		linker = S10_LINKER;
+#if defined(_LP64)
+	} else {
+		args->emulator = S10_LIB32;
+		linker = S10_LINKER32;
+#endif /* _LP64 */
+	}
+
+	if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP,
+	    &nvp)) != 0) {
+		uprintf("%s: not found.", args->emulator);
+		return (err);
+	}
+
+	if (args->to_model == DATAMODEL_NATIVE) {
+		err = elfexec(nvp, uap, args, idatap, level + 1, execsz,
+		    setid, exec_file, cred, brand_action);
+#if defined(_LP64)
+	} else {
+		err = elf32exec(nvp, uap, args, idatap, level + 1, execsz,
+		    setid, exec_file, cred, brand_action);
+#endif /* _LP64 */
+	}
+	VN_RELE(nvp);
+	if (err != 0)
+		return (err);
+
+	/*
+	 * The u_auxv vectors are set up by elfexec to point to the brand
+	 * emulation library and linker.  Save these so they can be copied to
+	 * the specific brand aux vectors.
+	 */
+	bzero(&sed, sizeof (sed));
+	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
+		switch (up->u_auxv[i].a_type) {
+		case AT_SUN_LDDATA:
+			sed.sed_lddata = up->u_auxv[i].a_un.a_val;
+			break;
+		case AT_BASE:
+			sed.sed_base = up->u_auxv[i].a_un.a_val;
+			break;
+		case AT_ENTRY:
+			sed.sed_entry = up->u_auxv[i].a_un.a_val;
+			break;
+		case AT_PHDR:
+			sed.sed_phdr = up->u_auxv[i].a_un.a_val;
+			break;
+		case AT_PHENT:
+			sed.sed_phent = up->u_auxv[i].a_un.a_val;
+			break;
+		case AT_PHNUM:
+			sed.sed_phnum = up->u_auxv[i].a_un.a_val;
+			break;
+		default:
+			break;
+		}
+	}
+	/* Make sure the emulator has an entry point */
+	ASSERT(sed.sed_entry != NULL);
+	ASSERT(sed.sed_phdr != NULL);
+
+	bzero(&env, sizeof (env));
+	if (args->to_model == DATAMODEL_NATIVE) {
+		err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset,
+		    exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase,
+		    &env.ex_brksize, NULL);
+#if defined(_LP64)
+	} else {
+		Elf32_Ehdr ehdr32;
+		Elf32_Addr uphdr_vaddr32;
+		err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
+		    &voffset, exec_file, &interp, &env.ex_bssbase,
+		    &env.ex_brkbase, &env.ex_brksize, NULL);
+		Ehdr32to64(&ehdr32, &ehdr);
+		if (uphdr_vaddr32 == (Elf32_Addr)-1)
+			uphdr_vaddr = (Addr)-1;
+		else
+			uphdr_vaddr = uphdr_vaddr32;
+#endif /* _LP64 */
+	}
+	if (err != 0)
+		return (err);
+
+	/*
+	 * Save off the important properties of the executable. The brand
+	 * library will ask us for this data later, when it is initializing
+	 * and getting ready to transfer control to the brand application.
+	 */
+	if (uphdr_vaddr == (Addr)-1)
+		sedp->sed_phdr = voffset + ehdr.e_phoff;
+	else
+		sedp->sed_phdr = voffset + uphdr_vaddr;
+	sedp->sed_entry = voffset + ehdr.e_entry;
+	sedp->sed_phent = ehdr.e_phentsize;
+	sedp->sed_phnum = ehdr.e_phnum;
+
+	if (interp) {
+		if (ehdr.e_type == ET_DYN) {
+			/*
+			 * This is a shared object executable, so we need to
+			 * pick a reasonable place to put the heap. Just don't
+			 * use the first page.
+			 */
+			env.ex_brkbase = (caddr_t)PAGESIZE;
+			env.ex_bssbase = (caddr_t)PAGESIZE;
+		}
+
+		/*
+		 * If the program needs an interpreter (most do), map it in and
+		 * store relevant information about it in the aux vector, where
+		 * the brand library can find it.
+		 */
+		if ((err = lookupname(linker, UIO_SYSSPACE,
+		    FOLLOW, NULLVPP, &nvp)) != 0) {
+			uprintf("%s: not found.", S10_LINKER);
+			return (err);
+		}
+		if (args->to_model == DATAMODEL_NATIVE) {
+			err = mapexec_brand(nvp, args, &ehdr,
+			    &uphdr_vaddr, &voffset, exec_file, &interp,
+			    NULL, NULL, NULL, &lddata);
+#if defined(_LP64)
+		} else {
+			Elf32_Ehdr ehdr32;
+			Elf32_Addr uphdr_vaddr32;
+			err = mapexec32_brand(nvp, args, &ehdr32,
+			    &uphdr_vaddr32, &voffset, exec_file, &interp,
+			    NULL, NULL, NULL, &lddata);
+			Ehdr32to64(&ehdr32, &ehdr);
+			if (uphdr_vaddr32 == (Elf32_Addr)-1)
+				uphdr_vaddr = (Addr)-1;
+			else
+				uphdr_vaddr = uphdr_vaddr32;
+#endif /* _LP64 */
+		}
+		VN_RELE(nvp);
+		if (err != 0)
+			return (err);
+
+		/*
+		 * Now that we know the base address of the brand's linker,
+		 * place it in the aux vector.
+		 */
+		sedp->sed_base = voffset;
+		sedp->sed_ldentry = voffset + ehdr.e_entry;
+		sedp->sed_lddata = voffset + lddata;
+	} else {
+		/*
+		 * This program has no interpreter. The brand library will
+		 * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector,
+		 * so in this case, put the entry point of the main executable
+		 * there.
+		 */
+		if (ehdr.e_type == ET_EXEC) {
+			/*
+			 * An executable with no interpreter, this must be a
+			 * statically linked executable, which means we loaded
+			 * it at the address specified in the elf header, in
+			 * which case the e_entry field of the elf header is an
+			 * absolute address.
+			 */
+			sedp->sed_ldentry = ehdr.e_entry;
+			sedp->sed_entry = ehdr.e_entry;
+			sedp->sed_lddata = NULL;
+			sedp->sed_base = NULL;
+		} else {
+			/*
+			 * A shared object with no interpreter, we use the
+			 * calculated address from above.
+			 */
+			sedp->sed_ldentry = sedp->sed_entry;
+			sedp->sed_entry = NULL;
+			sedp->sed_phdr = NULL;
+			sedp->sed_phent = NULL;
+			sedp->sed_phnum = NULL;
+			sedp->sed_lddata = NULL;
+			sedp->sed_base = voffset;
+
+			if (ehdr.e_type == ET_DYN) {
+				/*
+				 * Delay setting the brkbase until the first
+				 * call to brk(); see elfexec() for details.
+				 */
+				env.ex_bssbase = (caddr_t)0;
+				env.ex_brkbase = (caddr_t)0;
+				env.ex_brksize = 0;
+			}
+		}
+	}
+
+	env.ex_magic = elfmagic;
+	env.ex_vp = vp;
+	setexecenv(&env);
+
+	/*
+	 * It's time to manipulate the process aux vectors.  First
+	 * we need to update the AT_SUN_AUXFLAGS aux vector to set
+	 * the AF_SUN_NOPLM flag.
+	 */
+	if (args->to_model == DATAMODEL_NATIVE) {
+		auxv_t		auxflags_auxv;
+
+		if (copyin(args->auxp_auxflags, &auxflags_auxv,
+		    sizeof (auxflags_auxv)) != 0)
+			return (EFAULT);
+
+		ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
+		auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
+		if (copyout(&auxflags_auxv, args->auxp_auxflags,
+		    sizeof (auxflags_auxv)) != 0)
+			return (EFAULT);
+#if defined(_LP64)
+	} else {
+		auxv32_t	auxflags_auxv32;
+
+		if (copyin(args->auxp_auxflags, &auxflags_auxv32,
+		    sizeof (auxflags_auxv32)) != 0)
+			return (EFAULT);
+
+		ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
+		auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
+		if (copyout(&auxflags_auxv32, args->auxp_auxflags,
+		    sizeof (auxflags_auxv32)) != 0)
+			return (EFAULT);
+#endif /* _LP64 */
+	}
+
+	/* Second, copy out the brand specific aux vectors. */
+	if (args->to_model == DATAMODEL_NATIVE) {
+		auxv_t s10_auxv[] = {
+		    { AT_SUN_BRAND_AUX1, 0 },
+		    { AT_SUN_BRAND_AUX2, 0 },
+		    { AT_SUN_BRAND_AUX3, 0 }
+		};
+
+		ASSERT(s10_auxv[0].a_type == AT_SUN_BRAND_S10_LDDATA);
+		s10_auxv[0].a_un.a_val = sed.sed_lddata;
+
+		if (copyout(&s10_auxv, args->auxp_brand,
+		    sizeof (s10_auxv)) != 0)
+			return (EFAULT);
+#if defined(_LP64)
+	} else {
+		auxv32_t s10_auxv32[] = {
+		    { AT_SUN_BRAND_AUX1, 0 },
+		    { AT_SUN_BRAND_AUX2, 0 },
+		    { AT_SUN_BRAND_AUX3, 0 }
+		};
+
+		ASSERT(s10_auxv32[0].a_type == AT_SUN_BRAND_S10_LDDATA);
+		s10_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
+		if (copyout(&s10_auxv32, args->auxp_brand,
+		    sizeof (s10_auxv32)) != 0)
+			return (EFAULT);
+#endif /* _LP64 */
+	}
+
+	/*
+	 * Third, the the /proc aux vectors set up by elfexec() point to brand
+	 * emulation library and it's linker.  Copy these to the /proc brand
+	 * specific aux vector, and update the regular /proc aux vectors to
+	 * point to the executable (and it's linker).  This will enable
+	 * debuggers to access the executable via the usual /proc or elf notes
+	 * aux vectors.
+	 *
+	 * The brand emulation library's linker will get it's aux vectors off
+	 * the stack, and then update the stack with the executable's aux
+	 * vectors before jumping to the executable's linker.
+	 *
+	 * Debugging the brand emulation library must be done from
+	 * the global zone, where the librtld_db module knows how to fetch the
+	 * brand specific aux vectors to access the brand emulation libraries
+	 * linker.
+	 */
+	for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
+		ulong_t val;
+
+		switch (up->u_auxv[i].a_type) {
+		case AT_SUN_BRAND_S10_LDDATA:
+			up->u_auxv[i].a_un.a_val = sed.sed_lddata;
+			continue;
+		case AT_BASE:
+			val = sedp->sed_base;
+			break;
+		case AT_ENTRY:
+			val = sedp->sed_entry;
+			break;
+		case AT_PHDR:
+			val = sedp->sed_phdr;
+			break;
+		case AT_PHENT:
+			val = sedp->sed_phent;
+			break;
+		case AT_PHNUM:
+			val = sedp->sed_phnum;
+			break;
+		case AT_SUN_LDDATA:
+			val = sedp->sed_lddata;
+			break;
+		default:
+			continue;
+		}
+
+		up->u_auxv[i].a_un.a_val = val;
+		if (val == NULL) {
+			/* Hide the entry for static binaries */
+			up->u_auxv[i].a_type = AT_IGNORE;
+		}
+	}
+
+	/*
+	 * The last thing we do here is clear spd->spd_handler.  This is
+	 * important because if we're already a branded process and if this
+	 * exec succeeds, there is a window between when the exec() first
+	 * returns to the userland of the new process and when our brand
+	 * library get's initialized, during which we don't want system
+	 * calls to be re-directed to our brand library since it hasn't
+	 * been initialized yet.
+	 */
+	spd->spd_handler = NULL;
+
+	return (0);
+}
+
+
+int
+_init(void)
+{
+	int err;
+
+	/*
+	 * Set up the table indicating which system calls we want to
+	 * interpose on.  We should probably build this automatically from
+	 * a list of system calls that is shared with the user-space
+	 * library.
+	 */
+	s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
+	s10_emulation_table[SYS_exec] = 1;			/*  11 */
+	s10_emulation_table[SYS_ioctl] = 1;			/*  54 */
+	s10_emulation_table[SYS_execve] = 1;			/*  59 */
+	s10_emulation_table[SYS_acctctl] = 1;			/*  71 */
+	s10_emulation_table[S10_SYS_issetugid] = 1;		/*  75 */
+	s10_emulation_table[SYS_uname] = 1;			/* 135 */
+	s10_emulation_table[SYS_systeminfo] = 1;		/* 139 */
+#ifdef	__amd64
+	s10_emulation_table[SYS_lwp_create] = 1;		/* 159 */
+	s10_emulation_table[SYS_lwp_private] = 1;		/* 166 */
+#endif	/* __amd64 */
+	s10_emulation_table[SYS_pwrite] = 1;			/* 174 */
+	s10_emulation_table[SYS_auditsys] = 1;			/* 186 */
+	s10_emulation_table[SYS_sigqueue] = 1;			/* 190 */
+	s10_emulation_table[SYS_pwrite64] = 1;			/* 223 */
+	s10_emulation_table[SYS_zone] = 1;			/* 227 */
+
+	err = mod_install(&modlinkage);
+	if (err) {
+		cmn_err(CE_WARN, "Couldn't install brand module");
+		kmem_free(s10_emulation_table, NSYSCALL);
+	}
+
+	return (err);
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
+
+int
+_fini(void)
+{
+	int err;
+
+	/*
+	 * If there are any zones using this brand, we can't allow it to be
+	 * unloaded.
+	 */
+	if (brand_zone_count(&s10_brand))
+		return (EBUSY);
+
+	kmem_free(s10_emulation_table, NSYSCALL);
+	s10_emulation_table = NULL;
+
+	err = mod_remove(&modlinkage);
+	if (err)
+		cmn_err(CE_WARN, "Couldn't unload s10 brand module");
+
+	return (err);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/brand/solaris10/s10_brand.h	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,162 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _S10_BRAND_H
+#define	_S10_BRAND_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#define	S10_BRANDNAME		"solaris10"
+
+#define	S10_VERSION_1		1
+#define	S10_VERSION		S10_VERSION_1
+
+#define	S10_NATIVE_DIR		"/.SUNWnative/"
+#define	S10_LIB_NAME		"s10_brand.so.1"
+#define	S10_LINKER_NAME		"ld.so.1"
+
+#define	S10_LIB32		S10_NATIVE_DIR "usr/lib/" S10_LIB_NAME
+#define	S10_LINKER32		"/lib/" S10_LINKER_NAME
+#define	S10_NATIVE_LINKER32	S10_NATIVE_DIR "lib/" S10_LINKER_NAME
+
+#define	S10_LIB64		S10_NATIVE_DIR "usr/lib/64/" S10_LIB_NAME
+#define	S10_LINKER64		"/lib/64/" S10_LINKER_NAME
+#define	S10_NATIVE_LINKER64	S10_NATIVE_DIR "lib/64/" S10_LINKER_NAME
+
+#if defined(_LP64)
+#define	S10_LIB		S10_LIB64
+#define	S10_LINKER	S10_LINKER64
+#else /* !_LP64 */
+#define	S10_LIB		S10_LIB32
+#define	S10_LINKER	S10_LINKER32
+#endif /* !_LP64 */
+
+/*
+ * Brand system call subcodes.  0-127 are reserved for generic subcodes.
+ */
+#define	B_S10_PIDINFO		128
+#define	B_S10_TRUSS_POINT	129
+#define	B_S10_NATIVE		130
+#define	B_S10_FSREGCORRECTION	131
+
+/*
+ * s10_brand_syscall_callback_common() needs to save 4 local registers so it
+ * can free them up for its own use.
+ */
+#define	S10_CPU_REG_SAVE_SIZE	(sizeof (ulong_t) * 4)
+
+/*
+ * Aux vector containing lddata pointer of brand library linkmap.
+ * Used by s10_librtld_db.
+ */
+#define	AT_SUN_BRAND_S10_LDDATA		AT_SUN_BRAND_AUX1
+
+/*
+ * S10 system call codes for S10 traps that have been removed or
+ * re-assigned.
+ */
+#define	S10_SYS_issetugid	75
+
+/*
+ * S10 brand emulation versions are used to trigger different behavior
+ * based on the version of S10 installed in the zone.
+ */
+#define	S10_EMUL_UNDEF	-1
+
+#define	S10_EMUL_VERSION_NUM	ZONE_ATTR_BRAND_ATTRS
+
+/*
+ * Information needed by the s10 library to launch an executable.
+ */
+typedef struct s10_elf_data {
+	ulong_t		sed_phdr;
+	ulong_t		sed_phent;
+	ulong_t		sed_phnum;
+	ulong_t		sed_entry;
+	ulong_t		sed_base;
+	ulong_t		sed_ldentry;
+	ulong_t		sed_lddata;
+} s10_elf_data_t;
+
+/*
+ * Structure used to register a branded processes
+ */
+typedef struct s10_brand_reg {
+	uint_t		sbr_version;	/* version number */
+	caddr_t		sbr_handler;	/* base address of handler */
+} s10_brand_reg_t;
+
+#if defined(_KERNEL)
+#if defined(_SYSCALL32)
+typedef struct s10_elf_data32 {
+	uint32_t	sed_phdr;
+	uint32_t	sed_phent;
+	uint32_t	sed_phnum;
+	uint32_t	sed_entry;
+	uint32_t	sed_base;
+	uint32_t	sed_ldentry;
+	uint32_t	sed_lddata;
+} s10_elf_data32_t;
+
+typedef struct s10_brand_reg32 {
+	uint32_t	sbr_version;	/* version number */
+	caddr32_t	sbr_handler;	/* base address of handler */
+} s10_brand_reg32_t;
+#endif /* _SYSCALL32 */
+
+/*
+ * Information associated with all s10 branded processes
+ */
+typedef struct s10_proc_data {
+	caddr_t		spd_handler;	/* address of user-space handler */
+	s10_elf_data_t	spd_elf_data;	/* ELF data for s10 application */
+} s10_proc_data_t;
+
+/* brand specific data */
+typedef struct s10_zone_data {
+	int s10zd_emul_version;
+} s10_zone_data_t;
+
+void s10_brand_syscall_callback(void);
+void s10_brand_syscall32_callback(void);
+
+#if !defined(sparc)
+void s10_brand_sysenter_callback(void);
+#endif /* !sparc */
+
+#if defined(__amd64)
+void s10_brand_int91_callback(void);
+#endif /* __amd64 */
+#endif /* _KERNEL */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _S10_BRAND_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/brand/solaris10/s10_offsets.in	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,30 @@
+\
+\ Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+\ Use is subject to license terms.
+\
+\ CDDL HEADER START
+\
+\ The contents of this file are subject to the terms of the
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
+\
+\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+\ or http://www.opensolaris.org/os/licensing.
+\ See the License for the specific language governing permissions
+\ and limitations under the License.
+\
+\ When distributing Covered Code, include this CDDL HEADER in each
+\ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+\ If applicable, add the following below this CDDL HEADER, with the
+\ fields enclosed by brackets "[]" replaced with your own identifying
+\ information: Portions Copyright [yyyy] [name of copyright owner]
+\
+\ CDDL HEADER END
+\
+\ s10 brand structure offset for use in assembly code.
+\
+
+#include <s10_brand.h>
+
+s10_proc_data_t
+	spd_handler
--- a/usr/src/uts/intel/Makefile.files	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/intel/Makefile.files	Thu Oct 22 11:21:27 2009 -0700
@@ -260,6 +260,7 @@
 #	Brand modules
 #
 SN1_BRAND_OBJS	=	sn1_brand.o sn1_brand_asm.o
+S10_BRAND_OBJS	=	s10_brand.o s10_brand_asm.o
 
 LX_BRAND_OBJS  =		\
 	lx_brand.o		\
--- a/usr/src/uts/intel/Makefile.intel.shared	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/intel/Makefile.intel.shared	Thu Oct 22 11:21:27 2009 -0700
@@ -512,7 +512,7 @@
 #
 #	Brand modules
 #
-BRAND_KMODS	+= sn1_brand lx_brand
+BRAND_KMODS	+= sn1_brand s10_brand lx_brand
 DRV_KMODS	+= lx_systrace lx_ptm lx_audio
 STRMOD_KMODS	+= ldlinux
 
--- a/usr/src/uts/intel/Makefile.rules	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/intel/Makefile.rules	Thu Oct 22 11:21:27 2009 -0700
@@ -60,6 +60,9 @@
 $(OBJS_DIR)/%.o:		$(UTSBASE)/intel/brand/sn1/%.s
 	$(COMPILE.s) -o $@ $<
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/intel/brand/solaris10/%.s
+	$(COMPILE.s) -o $@ $<
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/intel/dtrace/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -315,6 +318,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/intel/brand/sn1/%.s
 	@($(LHEAD) $(LINT.s) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/intel/brand/solaris10/%.s
+	@($(LHEAD) $(LINT.s) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/intel/dtrace/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/brand/solaris10/s10_brand_asm.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,403 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#if defined(lint)
+
+#include <sys/systm.h>
+
+#else	/* lint */
+
+#include <sys/asm_linkage.h>
+#include <sys/privregs.h>
+#include <sys/segments.h>
+#include <s10_offsets.h>
+#include "assym.h"
+
+#endif	/* lint */
+
+#ifdef	lint
+
+void
+s10_brand_sysenter_callback(void)
+{
+}
+
+void
+s10_brand_syscall_callback(void)
+{
+}
+
+#if defined(__amd64)
+void
+s10_brand_syscall32_callback(void)
+{
+}
+#endif	/* amd64 */
+
+void
+s10_brand_int91_callback(void)
+{
+}
+
+#else	/* lint */
+
+#if defined(__amd64)
+/*
+ * When our syscall interposition callback entry point gets invoked the
+ * stack looks like this:
+ *         --------------------------------------
+ *      40 | user %gs				|
+ *      32 | callback pointer			|
+ *      24 | saved stack pointer		|
+ *    | 16 | lwp pointer			|
+ *    v  8 | user return address (*)		|
+ *       0 | BRAND_CALLBACK()'s return addr 	|
+ *         --------------------------------------
+ *   (*) This is actually just the bottom value from the user's
+ *       stack.  syscall puts this in %rcx instead of the stack,
+ *       so it's just garbage for that entry point.
+ */
+
+#define	V_COUNT	6
+#define	V_END		(CLONGSIZE * 6)
+#define	V_SSP		(CLONGSIZE * 3)
+#define	V_LWP		(CLONGSIZE * 2)
+#define	V_URET_ADDR	(CLONGSIZE * 1)
+#define	V_CB_ADDR	(CLONGSIZE * 0)
+
+#define	SP_REG		%rsp
+
+#else	/* !__amd64 */
+/*
+ * When our syscall interposition callback entry point gets invoked the
+ * stack looks like this:
+ *         --------------------------------------
+ *    | 24 | 'scratch space'			|
+ *    | 20 | user's %ebx			|
+ *    | 16 | user's %gs selector		|
+ *    | 12 | kernel's %gs selector		|
+ *    |  8 | lwp pointer			|
+ *    v  4 | user return address		|
+ *       0 | callback wrapper return addr	|
+ *         --------------------------------------
+ */
+
+#define	V_COUNT	7
+#define	V_END		(CLONGSIZE * 7)
+#define	V_U_GS		(CLONGSIZE * 4)
+#define	V_K_GS		(CLONGSIZE * 3)
+#define	V_LWP		(CLONGSIZE * 2)
+#define	V_URET_ADDR	(CLONGSIZE * 1)
+#define	V_CB_ADDR	(CLONGSIZE * 0)
+
+#define	SP_REG		%esp
+
+#endif	/* !__amd64 */
+
+/*
+ * The following macros allow us to access to variables/parameters passed
+ * in on the stack.  They take the following variables:
+ *	sp	- a register with the current stack pointer value
+ *	pcnt	- the number of words currently pushed onto the stack
+ *	var	- the variable to lookup
+ *	reg	- a register to read the variable into, or
+ *		  a register to write to the variable
+ */
+#define V_OFFSET(pcnt, var)						 \
+	(var + (pcnt * CLONGSIZE))
+
+#define GET_V(sp, pcnt, var, reg)					 \
+	mov	V_OFFSET(pcnt, var)(sp), reg
+
+#define SET_V(sp, pcnt, var, reg)					 \
+	mov	reg, V_OFFSET(pcnt, var)(sp)
+
+#define GET_PROCP(sp, pcnt, reg)					 \
+	GET_V(sp, pcnt, V_LWP, reg)		/* get lwp pointer */	;\
+	mov	LWP_PROCP(reg), reg		/* get proc pointer */
+
+#define GET_P_BRAND_DATA(sp, pcnt, reg)					 \
+	GET_PROCP(sp, pcnt, reg)					;\
+	mov	P_BRAND_DATA(reg), reg		/* get p_brand_data */
+
+/*
+ * Each of the following macros returns to the standard syscall codepath if
+ * it detects that this process is not able, or intended, to emulate this
+ * system call.  They all assume that the routine provides a 'bail-out'
+ * label of '9'.
+ */
+
+/*
+ * See if this process has a user-space hdlr registered for it.  For the
+ * s10 brand, the per-process brand data holds the address of the handler.
+ * As shown in the stack diagrams below, the callback code leaves that data
+ * at these offsets.  So check if s10_proc_data_t->spd_handler is non-NULL.
+ */
+#define	CHECK_FOR_HANDLER(scr)						 \
+	GET_P_BRAND_DATA(SP_REG, 1, scr)	/* get p_brand_data */	;\
+	cmp	$0, scr							;\
+	je	9f							;\
+	cmp	$0, SPD_HANDLER(scr)		/* check spd_handler */ ;\
+	je	9f
+
+/*
+ * If the system call number is >= 1024, then it is coming from the
+ * emulation support library.  As such we should handle it natively instead
+ * of sending it back to the emulation library.
+ */
+#define	CHECK_FOR_NATIVE(reg)		 \
+	cmp	$1024, reg		;\
+	jl	1f			;\
+	sub	$1024, reg		;\
+	jmp	9f			;\
+1:
+
+/*
+ * Check to see if we want to interpose on this system call.  If not, we
+ * jump back into the normal syscall path and pretend nothing happened.
+ */
+#define CHECK_FOR_INTERPOSITION(sysr, scr, scr_low)		 \
+	lea	s10_emulation_table, scr			;\
+	mov	(scr), scr					;\
+	add	sysr, scr					;\
+	movb	(scr), scr_low					;\
+	cmpb	$0, scr_low					;\
+	je	9f
+
+#define	CALLBACK_PROLOGUE(call, scr, scr_low)			 \
+	push	scr		/* Save scratch register */	;\
+	CHECK_FOR_HANDLER(scr)					;\
+	CHECK_FOR_NATIVE(call)					;\
+	CHECK_FOR_INTERPOSITION(call, scr, scr_low)
+
+/*
+ * The callback routines:
+ */
+
+#if defined(__amd64)
+
+/*
+ * syscall handler for 32-bit user processes:
+ *	%rax - syscall number
+ *	%ecx - the address of the instruction after the syscall
+ */
+ENTRY(s10_brand_syscall32_callback)
+
+	CALLBACK_PROLOGUE(%rax, %r15, %r15b)
+	movq	%rsp, %r15	/* save our stack pointer */
+
+	/*
+	 * Adjust the user's stack so that the 'ret' from our user-space
+	 * hdlr takes us to the post-syscall instruction instead of to
+	 * the routine that called the system call.
+	 */
+	GET_V(%r15, 1, V_SSP, %rsp) /* restore user's stack pointer	*/
+	subq	$4, %rsp	/* save room for the post-syscall addr	*/
+	movl	%ecx, (%rsp)	/* Save post-syscall addr on stack	*/
+
+	/*
+	 * To 'return' to our user-space handler, we just need to copy
+	 * its address into %rcx.
+	 */
+	GET_P_BRAND_DATA(%r15, 1, %rcx);/* get p_brand_data ptr	*/
+	movq	SPD_HANDLER(%rcx), %rcx	/* get p_brand_data->spd_handler ptr */
+	movq	(%r15), %r15		/* Restore scratch register	*/
+	jmp	nopop_sys_syscall32_swapgs_sysretl
+9:
+	popq	%r15
+	retq
+SET_SIZE(s10_brand_syscall32_callback)
+
+/*
+ * syscall handler for 64-bit user processes:
+ *     %rax - syscall number
+ *     %rcx - user space %rip
+ */
+ENTRY(s10_brand_syscall_callback)
+
+	CALLBACK_PROLOGUE(%rax, %r15, %r15b)
+	movq	%rsp, %r15	/* save our stack pointer */
+
+	GET_V(%r15, 1, V_SSP, %rsp) /* restore user's stack pointer	*/
+	subq	$8, %rsp	/* save room for the post-syscall addr	*/
+	movq	%rcx, (%rsp)	/* Save post-syscall addr on stack	*/
+
+	/*
+	 * To 'return' to our user-space handler, we just need to copy
+	 * its address into %rcx.
+	 */
+	GET_P_BRAND_DATA(%r15, 1, %rcx);/* get p_brand_data ptr	*/
+	movq	SPD_HANDLER(%rcx), %rcx	/* get p_brand_data->spd_handler ptr */
+	movq	(%r15), %r15		/* Restore scratch register	*/
+	jmp	nopop_sys_syscall_swapgs_sysretq
+9:
+	popq	%r15
+	retq
+
+SET_SIZE(s10_brand_syscall_callback)
+
+/*
+ * %eax - syscall number
+ * %ecx - user space %esp
+ * %edx - user space return address
+ */
+ENTRY(s10_brand_sysenter_callback)
+
+	CALLBACK_PROLOGUE(%rax, %r15, %r15b)
+
+	subl	$4, %ecx		/* Save room for user ret addr	*/
+	movl	%edx, (%rcx)		/* Save current return addr	*/
+	GET_P_BRAND_DATA(%rsp, 1, %rdx)	/* get p_brand_data		*/
+	movq	SPD_HANDLER(%rdx), %rdx	/* get p_brand_data->spd_handler ptr */
+	popq	%r15			/* Restore scratch register	*/
+	jmp	sys_sysenter_swapgs_sysexit
+9:
+	popq	%r15
+	ret
+SET_SIZE(s10_brand_sysenter_callback)
+
+/*
+ * The saved stack pointer points at the state saved when we took
+ * the interrupt:
+ *	   --------------------------------------
+ *    | 32 | user's %ss				|
+ *    | 24 | user's %esp			|
+ *    | 16 | EFLAGS register			|
+ *    v  8 | user's %cs				|
+ *       0 | user's %eip			|
+ *	   --------------------------------------
+ */
+ENTRY(s10_brand_int91_callback)
+
+	CALLBACK_PROLOGUE(%rax, %r15, %r15b)
+	pushq	%rax				/* Save scratch register */
+
+	GET_P_BRAND_DATA(%rsp, 2, %r15)	/* get p_brand_data */
+	movq	SPD_HANDLER(%r15), %r15	/* get s10_proc_data->spd_handler ptr */
+	GET_V(%rsp, 2, V_SSP, %rax)	/* Get saved %esp */
+	movq	%r15, (%rax)	/* replace iret target address with hdlr */
+
+	/*
+	 * Adjust the caller's stack so we return to the instruction after
+	 * the syscall on the next 'ret' in userspace - not to the parent
+	 * routine.
+	 */
+	movq	24(%rax), %r15	/* Get user's %esp			*/
+	subq	$4, %r15	/* Make room for new ret addr		*/
+	movq	%r15, 24(%rax)	/* Replace current with updated %esp	*/
+
+	GET_V(%rsp, 2, V_URET_ADDR, %rax)
+	movl	%eax, (%r15)	/* Put it on the user's stack		*/
+
+	popq	%rax			/* Restore scratch register	*/
+	popq	%r15			/* Restore scratch register	*/
+	movq	V_SSP(%rsp), %rsp	/* Remove callback stuff from stack */
+	jmp	sys_sysint_swapgs_iret
+9:
+	popq	%r15
+	retq
+SET_SIZE(s10_brand_int91_callback)
+
+#else	/* !__amd64 */
+
+/*
+ * lcall handler for 32-bit OS
+ *     %eax - syscall number
+ *
+ * Above the stack contents common to all callbacks is the
+ * int/lcall-specific state:
+ *	   --------------------------------------
+ *    | 44 | user's %ss				|
+ *    | 40 | user's %esp			|
+ *    | 36 | EFLAGS register			|
+ *    v 32 | user's %cs				|
+ *      28 | user's %eip			|
+ *	   --------------------------------------
+ */
+#define	V_U_SS		(V_END + (CLONGSIZE * 4))
+#define	V_U_ESP		(V_END + (CLONGSIZE * 3))
+#define	V_EFLAGS	(V_END + (CLONGSIZE * 2))
+#define	V_U_CS		(V_END + (CLONGSIZE * 1))
+#define	V_U_EIP		(V_END + (CLONGSIZE * 0))
+
+ENTRY(s10_brand_syscall_callback)
+
+	CALLBACK_PROLOGUE(%eax, %ebx, %bl)
+	pushl	%eax				/* Save scratch register */
+
+	/* replace iret target address with user-space hdlr */
+	GET_P_BRAND_DATA(%esp, 2, %ebx)	/* get p_brand_data ptr		*/
+	movl	SPD_HANDLER(%ebx), %ebx	/* get p_brand_data->spd_handler ptr */
+	SET_V(%esp, 2, V_U_EIP, %ebx)	/* set iret target address to hdlr */
+
+	/*
+	 * Adjust the caller's stack so we return to the instruction after
+	 * the syscall on the next 'ret' in userspace - not to the parent
+	 * routine.
+	 */
+	GET_V(%esp, 2, V_URET_ADDR, %ebx) /* Get new post-syscall ret addr  */
+	GET_V(%esp, 2, V_U_ESP, %eax)	  /* Get user %esp		    */
+	subl	$4, %eax		  /* Make room for new ret addr	    */
+	SET_V(%esp, 2, V_U_ESP, %eax)	  /* Updated user %esp		    */
+	movl	%ebx, (%eax)		  /* Put new ret addr on user stack */
+
+	GET_V(%esp, 2, V_U_GS, %ebx)	  /* grab the the user %gs	*/
+	movw	%bx, %gs		  /* restore the user %gs	*/
+
+	popl	%eax		/* Restore scratch register 		*/
+	popl	%ebx		/* Restore scratch register 		*/
+	addl	$V_END, %esp	/* Remove all callback stuff from stack	*/
+	jmp	nopop_sys_rtt_syscall
+9:
+	popl	%ebx
+	ret
+SET_SIZE(s10_brand_syscall_callback)
+
+/*
+ * %eax - syscall number
+ * %ecx - user space %esp
+ * %edx - user space return address
+ */
+ENTRY(s10_brand_sysenter_callback)
+
+	CALLBACK_PROLOGUE(%eax, %ebx, %bl)
+
+	subl	$4, %ecx		/* Save room for user ret addr	*/
+	movl	%edx, (%ecx)		/* Save current return addr	*/
+	GET_P_BRAND_DATA(%esp, 1, %edx)	/* get p_brand_data		*/
+	movl	SPD_HANDLER(%edx), %edx	/* get p_brand_data->spd_handler */
+
+	GET_V(%esp, 1, V_U_GS, %ebx)	  /* grab the the user %gs	*/
+	movw	%bx, %gs		  /* restore the user %gs	*/
+
+	popl	%ebx			/* Restore scratch register	*/
+	sysexit
+9:
+	popl	%ebx
+	ret
+SET_SIZE(s10_brand_sysenter_callback)
+
+#endif	/* !__amd64 */
+#endif	/* lint */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/s10_brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,106 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#	This makefile drives the production of the kernel component of
+#	the Solaris 10 brand
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE =	../..
+S10_BASE =	$(UTSBASE)/common/brand/solaris10
+
+#
+#	Define the module and object file sets.
+#
+MODULE =	s10_brand
+OFFSETS_H =	$(OBJS_DIR)/s10_offsets.h
+OFFSETS_SRC =	$(S10_BASE)/s10_offsets.in
+OBJECTS =	$(S10_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS =		$(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE =	$(USR_BRAND_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET =		$(OFFSETS_H) $(BINARY)
+LINT_TARGET =		$(MODULE).lint
+INSTALL_TARGET =	$(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+
+
+#
+#	Update compiler variables.
+#
+INC_PATH +=	-I$(S10_BASE) -I$(OBJS_DIR)
+AS_INC_PATH	+= -I$(UTSBASE)/i86pc/genassym/$(OBJS_DIR)
+LDFLAGS +=	-dy -Nexec/elfexec
+
+#
+# Ugh, this is a gross hack.  s10_brand_asm.s uses lots of defines
+# to simplify variable access.  All these defines work fine for amd64
+# compiles because when compiling for amd64 we use the GNU assembler,
+# gas.  For 32-bit code we use the Sun assembler, as.  Unfortunatly
+# as does not handle certian constructs that gas does.  So rather than
+# make our code less readable, we'll just use gas to compile our 32-bit
+# code as well.
+#
+i386_AS		= $(amd64_AS)
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+# Create genassym.h
+#
+$(OFFSETS_H): $(OFFSETS_SRC)
+	$(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4/brand/solaris10/s10_brand_asm.s	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,290 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#if defined(lint)
+
+#include <sys/systm.h>
+
+void
+s10_brand_syscall32_callback(void)
+{
+}
+
+void
+s10_brand_syscall_callback(void)
+{
+}
+
+#else	/* !lint */
+
+#include <sys/asm_linkage.h>
+#include <sys/machthread.h>
+#include <sys/privregs.h>
+#include <s10_offsets.h>
+#include "assym.h"
+
+#if defined(sun4v)
+
+#define GLOBALS_SWAP(reg)				\
+	rdpr	%gl, reg				;\
+	wrpr	reg, 1, %gl
+
+/*
+ * The GLOBALS_RESTORE macro can only be one instruction since it's
+ * used in a delay slot.
+ */
+#define GLOBALS_RESTORE(reg)				\
+	wrpr	reg, 0, %gl
+
+#else /* !sun4v */
+
+#define GLOBALS_SWAP(reg)				\
+	rdpr	%pstate, reg				;\
+	wrpr	reg, PSTATE_AG, %pstate
+
+/*
+ * The GLOBALS_RESTORE macro can only be one instruction since it's
+ * used in a delay slot.
+ */
+#define GLOBALS_RESTORE(reg)				\
+	wrpr	reg, %g0, %pstate
+
+#endif /* !sun4v */
+
+	/*
+	 * Input parameters:
+	 * %g1: return point
+	 * %g2: pointer to our cpu structure
+	 */
+	ENTRY(s10_brand_syscall32_callback)
+	/*
+	 * If the trapping thread has the address mask bit clear, then it's
+	 * a 64-bit process, and has no business calling 32-bit syscalls.
+	 */
+	rdpr	%tstate, %g3		! %tstate.am is the trapping
+	andcc	%g3, TSTATE_AM, %g3	!   threads address mask bit
+	bne,pt	%xcc, _entry
+	nop
+	jmp	%g1			! 64 bit process, bail out
+	nop
+	SET_SIZE(s10_brand_syscall32_callback)
+
+	/*
+	 * Input parameters:
+	 * %g1: return point
+	 * %g2: pointer to our cpu structure
+	 */
+	ENTRY(s10_brand_syscall_callback)
+	/*
+	 * If the trapping thread has the address mask bit set, then it's
+	 * a 32-bit process, and has no business calling 64-bit syscalls.
+	 */
+	rdpr	%tstate, %g3		! %tstate.am is the trapping
+	andcc	%g3, TSTATE_AM, %g3	!   threads address mask bit
+	be,pt	%xcc, _entry
+	nop
+	jmp	%g1			! 32 bit process, bail out
+	nop
+	SET_SIZE(s10_brand_syscall_callback)
+
+	ENTRY(s10_brand_syscall_callback_common)
+_entry:
+	/*
+	 * Input parameters:
+	 * %g1: return point
+	 * %g2: pointer to our cpu structure
+	 *
+	 * Note that we're free to use any %g? registers as long as
+	 * we are are executing with alternate globals.  If we're
+	 * executing with user globals we need to backup any registers
+	 * that we want to use so that we can restore them when we're
+	 * done.
+	 *
+	 * Save some locals in the CPU tmp area to give us a little
+	 * room to work.
+	 */
+	stn	%l0, [%g2 + CPU_TMP1]
+	stn	%l1, [%g2 + CPU_TMP2]
+
+#if defined(sun4v)
+	/*
+	 * On sun4v save our input parameters (which are stored in the
+	 * alternate globals) since we'll need to switch between alternate
+	 * globals and normal globals, and on sun4v the alternate globals
+	 * are not preserved across these types of switches.
+	 */
+	stn	%l2, [%g2 + CPU_TMP3]
+	stn	%l3, [%g2 + CPU_TMP4]
+
+	mov	%g1, %l2		! save %g1 in %l2
+	mov	%g2, %l3		! save %g2 in %l3
+#endif /* sun4v */
+
+	/*
+	 * Switch from the alternate to user globals to grab the syscall
+	 * number.
+	 */
+	GLOBALS_SWAP(%l0)		! switch to normal globals
+
+	/*
+	 * If the system call number is >= 1024, then it is a native
+	 * syscall that doesn't need emulation.
+	 */
+	cmp	%g1, 1024		! is this a native syscall?
+	bl,a	_indirect_check		! probably not, continue checking
+	mov	%g1, %l1		! delay slot - grab syscall number
+
+	/*
+	 * This is a native syscall, probably from the emulation library.
+	 * Subtract 1024 from the syscall number and let it go through.
+	 */
+	sub	%g1, 1024, %g1		! convert magic num to real syscall
+	ba	_exit			! jump back into syscall path
+	GLOBALS_RESTORE(%l0)		! delay slot -
+					! switch back to alternate globals
+
+_indirect_check:
+	/*
+	 * If the system call number is 0 (SYS_syscall), then this might be
+	 * an indirect syscall, in which case the actual syscall number
+	 * would be stored in %o0, in which case we need to redo the
+	 * the whole >= 1024 check.
+	 */
+	brnz,pt %g1, _emulation_check	! is this an indirect syscall?
+	nop				! if not, goto the emulation check
+
+	/*
+	 * Indirect syscalls are only supported for 32 bit processes so
+	 * consult the tstate address mask again.
+	 */
+	rdpr	%tstate, %l1		! %tstate.am is the trapping
+	andcc	%l1, TSTATE_AM, %l1	!   threads address mask bit
+	be,a,pn	%xcc, _exit
+	GLOBALS_RESTORE(%l0)		! delay slot -
+					! switch back to alternate globals
+
+	/*
+	 * The caller is 32 bit and this an indirect system call.
+	 */
+	cmp	%o0, 1024		! is this a native syscall?
+	bl,a	_emulation_check	! no, goto the emulation check
+	mov	%o0, %l1		! delay slot - grab syscall number
+
+	/*
+	 * This is native indirect syscall, probably from the emulation library.
+	 * Subtract 1024 from the syscall number and let it go through.
+	 */
+	sub	%o0, 1024, %o0		! convert magic num to real syscall
+	ba	_exit			! jump back into syscall path
+	GLOBALS_RESTORE(%l0)		! delay slot -
+					! switch back to alternate globals
+
+_emulation_check:
+	GLOBALS_RESTORE(%l0)		! switch back to alternate globals
+
+	/*
+	 * Check to see if we want to interpose on this system call.  If
+	 * not, we jump back into the normal syscall path and pretend
+	 * nothing happened.  %l1 contains the syscall we're invoking.
+	 */
+	set	s10_emulation_table, %g3
+	ldn	[%g3], %g3
+	add	%g3, %l1, %g3
+	ldub	[%g3], %g3
+	brz	%g3, _exit
+	nop
+
+	/*
+	 * Find the address of the userspace handler.
+	 * cpu->cpu_thread->t_procp->p_brand_data->spd_handler.
+	 */
+#if defined(sun4v)
+	! restore the alternate global registers after incrementing %gl
+	mov	%l3, %g2
+#endif /* sun4v */
+	ldn	[%g2 + CPU_THREAD], %g3		! get thread ptr
+	ldn	[%g3 + T_PROCP], %g4		! get proc ptr
+	ldn	[%g4 + P_BRAND_DATA], %g5	! get brand data ptr
+	ldn	[%g5 + SPD_HANDLER], %g5	! get userland brand handler ptr
+	brz	%g5, _exit			! has it been set?
+	nop
+
+	/*
+	 * Make sure this isn't an agent lwp.  We can't do syscall
+	 * interposition for system calls made by a agent lwp.  See
+	 * the block comments in the top of the brand emulation library
+	 * for more information.
+	 */
+	ldn	[%g4 + P_AGENTTP], %g4		! get agent thread ptr
+	cmp	%g3, %g4			! is this an agent thread?
+	be,pn	%xcc, _exit			! if so don't emulate
+	nop
+
+	/*
+	 * Now the magic happens.  Grab the trap return address and then
+	 * reset it to point to the user space handler.  When we execute
+	 * the 'done' instruction, we will jump into our handler instead of
+	 * the user's code.  We also stick the old return address in %g5,
+	 * so we can return to the proper instruction in the user's code.
+	 * Note: we also pass back the base address of the syscall
+	 * emulation table.  This is a performance hack to avoid having to
+	 * look it up on every call.
+	 */
+	rdpr	%tnpc, %l1		! save old tnpc
+	wrpr	%g0, %g5, %tnpc		! setup tnpc
+	GLOBALS_SWAP(%l0)		! switch to normal globals
+	mov	%l1, %g5		! pass tnpc to user code in %g5
+	GLOBALS_RESTORE(%l0)		! switch back to alternate globals
+
+	/* Update the address we're going to return to */
+#if defined(sun4v)
+	set	fast_trap_done_chk_intr, %l2
+#else /* !sun4v */
+	set	fast_trap_done_chk_intr, %g1
+#endif /* !sun4v */
+
+_exit:
+	/*
+	 * Restore registers before returning.
+	 *
+	 * Note that %g2 should be loaded with the CPU struct addr and
+	 * %g1 should be loaded the address we're going to return to.
+	 */
+#if defined(sun4v)
+	! restore the alternate global registers after incrementing %gl
+	mov	%l2, %g1		! restore %g1 from %l2
+	mov	%l3, %g2		! restore %g2 from %l3
+
+	ldn	[%g2 + CPU_TMP4], %l3	! restore locals
+	ldn	[%g2 + CPU_TMP3], %l2
+#endif /* sun4v */
+
+	ldn	[%g2 + CPU_TMP2], %l1	! restore locals
+	ldn	[%g2 + CPU_TMP1], %l0
+
+	jmp	%g1
+	nop
+	SET_SIZE(s10_brand_syscall_callback_common)
+#endif	/* !lint */
--- a/usr/src/uts/sun4u/Makefile.files	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4u/Makefile.files	Thu Oct 22 11:21:27 2009 -0700
@@ -186,6 +186,7 @@
 #			Brand modules
 #
 SN1_BRAND_OBJS	= sn1_brand.o sn1_brand_asm.o
+S10_BRAND_OBJS	= s10_brand.o s10_brand_asm.o
 
 #
 #			Performance Counter BackEnd (PCBE) Modules
--- a/usr/src/uts/sun4u/Makefile.rules	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4u/Makefile.rules	Thu Oct 22 11:21:27 2009 -0700
@@ -20,11 +20,9 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 #	This Makefile defines the build rules for the directory uts/sun4u
 #	and its children. These are the source files which sun4u
 #	"implementation architecture" dependent.
@@ -108,6 +106,9 @@
 $(OBJS_DIR)/%.o:		$(UTSBASE)/sun4/brand/sn1/%.s
 	$(COMPILE.s) -o $@ $<
 
+$(OBJS_DIR)/%.o:                $(UTSBASE)/sun4/brand/solaris10/%.s
+	$(COMPILE.s) -o $@ $<
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/sun4u/vm/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -223,6 +224,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/sun4/brand/sn1/%.s
 	@($(LHEAD) $(LINT.s) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:              $(UTSBASE)/sun4/brand/solaris10/%.s
+	@($(LHEAD) $(LINT.s) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/sun4u/vm/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- a/usr/src/uts/sun4u/Makefile.sun4u.shared	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4u/Makefile.sun4u.shared	Thu Oct 22 11:21:27 2009 -0700
@@ -441,7 +441,7 @@
 #
 #	Brand modules
 #
-BRAND_KMODS	+= sn1_brand
+BRAND_KMODS	+= sn1_brand s10_brand
 
 #
 #	Software Cryptographic Providers (/kernel/crypto):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4u/s10_brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,93 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#	This makefile drives the production of the kernel component of
+#	the Solaris 10 brand
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE =	../..
+S10_BASE =	$(UTSBASE)/common/brand/solaris10
+
+#
+#	Define the module and object file sets.
+#
+MODULE =	s10_brand
+OFFSETS_H =	$(OBJS_DIR)/s10_offsets.h
+OFFSETS_SRC =	$(S10_BASE)/s10_offsets.in
+OBJECTS =	$(S10_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS =		$(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE =	$(ROOT_PSM_BRAND_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sun4u/Makefile.sun4u
+
+#
+#	Define targets
+#
+ALL_TARGET =		$(OFFSETS_H) $(BINARY)
+LINT_TARGET =		$(MODULE).lint
+INSTALL_TARGET =	$(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+
+#
+#	Update compiler variables.
+#
+INC_PATH +=	-I$(S10_BASE) -I$(OBJS_DIR)
+LDFLAGS +=	-dy -Nexec/elfexec
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+# Create genassym.h
+#
+$(OFFSETS_H): $(OFFSETS_SRC)
+	$(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sun4u/Makefile.targ
--- a/usr/src/uts/sun4v/Makefile.files	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4v/Makefile.files	Thu Oct 22 11:21:27 2009 -0700
@@ -173,6 +173,7 @@
 #			Brand modules
 #
 SN1_BRAND_OBJS		= sn1_brand.o sn1_brand_asm.o
+S10_BRAND_OBJS		= s10_brand.o s10_brand_asm.o
 
 #
 #			Performance Counter BackEnd (PCBE) Modules
--- a/usr/src/uts/sun4v/Makefile.rules	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4v/Makefile.rules	Thu Oct 22 11:21:27 2009 -0700
@@ -20,11 +20,9 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 #	This Makefile defines the build rules for the directory uts/sun4v
 #	and its children. These are the source files which sun4v
 #	"implementation architecture" dependent.
@@ -65,6 +63,9 @@
 $(OBJS_DIR)/%.o:		$(UTSBASE)/sun4/brand/sn1/%.s
 	$(COMPILE.s) -o $@ $<
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/sun4/brand/solaris10/%.s
+	$(COMPILE.s) -o $@ $<
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/sun4v/promif/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -213,6 +214,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/sun4/brand/sn1/%.s
 	@($(LHEAD) $(LINT.s) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/sun4/brand/solaris10/%.s
+	@($(LHEAD) $(LINT.s) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/sun4v/promif/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- a/usr/src/uts/sun4v/Makefile.sun4v.shared	Thu Oct 22 09:11:59 2009 -0600
+++ b/usr/src/uts/sun4v/Makefile.sun4v.shared	Thu Oct 22 11:21:27 2009 -0700
@@ -407,7 +407,7 @@
 #
 #	Brand modules
 #
-BRAND_KMODS	+= sn1_brand
+BRAND_KMODS	+= sn1_brand s10_brand
 
 #
 #	Software Cryptographic Providers (/kernel/crypto):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sun4v/s10_brand/Makefile	Thu Oct 22 11:21:27 2009 -0700
@@ -0,0 +1,93 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#	This makefile drives the production of the kernel component of
+#	the Solaris 10 brand
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE =	../..
+S10_BASE =	$(UTSBASE)/common/brand/solaris10
+
+#
+#	Define the module and object file sets.
+#
+MODULE =	s10_brand
+OFFSETS_H =	$(OBJS_DIR)/s10_offsets.h
+OFFSETS_SRC =	$(S10_BASE)/s10_offsets.in
+OBJECTS =	$(S10_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS =		$(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE =	$(ROOT_PSM_BRAND_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sun4v/Makefile.sun4v
+
+#
+#	Define targets
+#
+ALL_TARGET =		$(OFFSETS_H) $(BINARY)
+LINT_TARGET =		$(MODULE).lint
+INSTALL_TARGET =	$(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+
+#
+#	Update compiler variables.
+#
+INC_PATH +=	-I$(S10_BASE) -I$(OBJS_DIR)
+LDFLAGS +=	-dy -Nexec/elfexec
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+# Create genassym.h
+#
+$(OFFSETS_H): $(OFFSETS_SRC)
+	$(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sun4v/Makefile.targ