summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorEdward Pilatowicz <Edward.Pilatowicz@Sun.COM>2008-10-24 00:15:39 -0700
committerEdward Pilatowicz <Edward.Pilatowicz@Sun.COM>2008-10-24 00:15:39 -0700
commit628e3cbed6489fa1db545d8524a06cd6535af456 (patch)
treeb6b90c60191d6f14fc623246f31b7d65fc25dceb /usr/src
parenta231f2c8d4f0393e99ef88b6b6538113cf7c144f (diff)
downloadillumos-joyent-628e3cbed6489fa1db545d8524a06cd6535af456.tar.gz
6409860 sn1 brand should use elfexec()
6540437 sn1 brand doesn't support indirect system calls --HG-- rename : usr/src/lib/brand/sn1/Makefile.com => usr/src/lib/brand/sn1/sn1_brand/Makefile.com rename : usr/src/lib/brand/sn1/amd64/Makefile => usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile rename : usr/src/lib/brand/sn1/amd64/sn1_handler.s => usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s rename : usr/src/lib/brand/sn1/common/mapfile-vers => usr/src/lib/brand/sn1/sn1_brand/common/mapfile-vers rename : usr/src/lib/brand/sn1/common/sn1_brand.c => usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c rename : usr/src/lib/brand/sn1/i386/Makefile => usr/src/lib/brand/sn1/sn1_brand/i386/Makefile rename : usr/src/lib/brand/sn1/i386/sn1_handler.s => usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s rename : usr/src/lib/brand/sn1/sparc/Makefile => usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile rename : usr/src/lib/brand/sn1/sparc/sn1_handler.s => usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s rename : usr/src/lib/brand/sn1/sparcv9/Makefile => usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile rename : usr/src/lib/brand/sn1/common/sn1_brand.h => usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Targetdirs5
-rw-r--r--usr/src/lib/brand/sn1/Makefile28
-rw-r--r--usr/src/lib/brand/sn1/Makefile.com59
-rw-r--r--usr/src/lib/brand/sn1/Makefile.sn132
-rw-r--r--usr/src/lib/brand/sn1/amd64/sn1_handler.s371
-rw-r--r--usr/src/lib/brand/sn1/common/sn1_brand.c78
-rw-r--r--usr/src/lib/brand/sn1/common/sn1_brand.h47
-rw-r--r--usr/src/lib/brand/sn1/i386/sn1_handler.s390
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/Makefile51
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/Makefile.com80
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/amd64/Makefile (renamed from usr/src/lib/brand/sn1/amd64/Makefile)12
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/amd64/mapfile-vers29
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers43
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers.6429
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/common/sn1_librtld_db.c299
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/i386/Makefile (renamed from usr/src/lib/brand/sn1/i386/Makefile)11
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/sparc/Makefile (renamed from usr/src/lib/brand/sn1/sparc/Makefile)9
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/sparcv9/Makefile (renamed from usr/src/lib/brand/sn1/sparcv9/Makefile)14
-rw-r--r--usr/src/lib/brand/sn1/librtld_db/sparcv9/mapfile-vers29
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/Makefile49
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/Makefile.com105
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile41
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_crt.s73
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s182
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_runexe.s80
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/common/mapfile-vers (renamed from usr/src/lib/brand/sn1/common/mapfile-vers)3
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/common/offsets.in35
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c758
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/i386/Makefile39
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/i386/sn1_crt.s77
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s159
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/i386/sn1_runexe.s80
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile40
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_crt.s80
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s225
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_runexe.s82
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile41
-rw-r--r--usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h173
-rw-r--r--usr/src/lib/brand/sn1/sparc/sn1_handler.s421
-rw-r--r--usr/src/lib/brand/sn1/zone/platform.xml7
-rw-r--r--usr/src/lib/brand/sn1/zone/sn1_boot.sh22
-rw-r--r--usr/src/pkgdefs/SUNWsn1uint/prototype_i3868
-rw-r--r--usr/src/pkgdefs/SUNWsn1uint/prototype_sparc8
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_brand.c1
-rw-r--r--usr/src/uts/common/brand/sn1/sn1_brand.c501
-rw-r--r--usr/src/uts/common/brand/sn1/sn1_brand.h95
-rw-r--r--usr/src/uts/common/brand/sn1/sn1_offsets.in30
-rw-r--r--usr/src/uts/intel/brand/sn1/sn1_brand_asm.s49
-rw-r--r--usr/src/uts/intel/sn1_brand/Makefile34
-rw-r--r--usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s195
-rw-r--r--usr/src/uts/sun4u/sn1_brand/Makefile36
-rw-r--r--usr/src/uts/sun4v/sn1_brand/Makefile36
52 files changed, 3812 insertions, 1569 deletions
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index 700e33d334..c771e4231b 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -354,7 +354,8 @@ ROOT.BIN64= \
/usr/ccs/bin/$(MACH64) \
/usr/ccs/lib/$(MACH64) \
/usr/lib/$(MACH64) \
- /usr/lib/$(MACH64)/gss \
+ /usr/lib/$(MACH64)/gss \
+ /usr/lib/brand/sn1/$(MACH64) \
/usr/lib/elfedit/$(MACH64) \
/usr/lib/fm/$(MACH64) \
/usr/lib/fp/libp/$(MACH64) \
@@ -506,6 +507,7 @@ SYM.ROOT.BIN64= \
/lib/64 \
/lib/secure/64 \
/usr/lib/64 \
+ /usr/lib/brand/sn1/64 \
/usr/lib/elfedit/64 \
/usr/lib/libp/64 \
/usr/lib/link_audit/64 \
@@ -665,6 +667,7 @@ $(BUILD64) $(ROOT)/lib/secure/64:= LINKDEST=$(MACH64)
$(BUILD64) $(ROOT)/usr/lib/64:= LINKDEST=$(MACH64)
$(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/libp/64:= LINKDEST=$(MACH64)
$(BUILD64) $(ROOT)/usr/lib/lwp/64:= LINKDEST=$(MACH64)
$(BUILD64) $(ROOT)/usr/lib/link_audit/64:= LINKDEST=$(MACH64)
diff --git a/usr/src/lib/brand/sn1/Makefile b/usr/src/lib/brand/sn1/Makefile
index 27fccbb515..9eff18131b 100644
--- a/usr/src/lib/brand/sn1/Makefile
+++ b/usr/src/lib/brand/sn1/Makefile
@@ -19,27 +19,33 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-include ../../Makefile.lib
+default: all
+
+include Makefile.sn1
-SUBDIRS= $(MACH) $(VARIANT_SUBDIRS) zone
-$(BUILD64)SUBDIRS += $(MACH64)
+# Build everything in parallel; use .WAIT for dependencies
+.PARALLEL:
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-install := TARGET= install
-lint := TARGET= lint
+SUBDIRS = librtld_db sn1_brand zone
+MSGSUBDIRS = librtld_db sn1_brand 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)
diff --git a/usr/src/lib/brand/sn1/Makefile.com b/usr/src/lib/brand/sn1/Makefile.com
deleted file mode 100644
index d28805931e..0000000000
--- a/usr/src/lib/brand/sn1/Makefile.com
+++ /dev/null
@@ -1,59 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-
-LIBRARY = sn1_brand.a
-VERS = .1
-COBJS = sn1_brand.o
-ASOBJS = sn1_handler.o
-OBJECTS = $(COBJS) $(ASOBJS)
-
-include ../../../Makefile.lib
-
-LIBS = $(DYNLIB)
-CSRCS = $(COBJS:%o=../common/%c)
-ASSRCS = $(ASOBJS:%o=$(ISASRCDIR)/%s)
-SRCS = $(CSRCS) $(ASSRCS)
-SRCDIR = ../common
-
-LDLIBS += -Wl,-esn1_init -lc
-CFLAGS += $(CCVERBOSE)
-CPPFLAGS += -D_REENTRANT -I../common
-DYNFLAGS += $(BLOCAL) $(ZNOVERSION)
-ASFLAGS = -P $(ASFLAGS_$(CURTYPE)) -D_ASM -I../common
-
-.KEEP_STATE:
-
-all: $(LIBS)
-
-lint: lintcheck
-
-pics/%.o: $(ISASRCDIR)/%.s
- $(COMPILE.s) -o $@ $<
- $(POST_PROCESS_O)
-
-include ../../../Makefile.targ
-
diff --git a/usr/src/lib/brand/sn1/Makefile.sn1 b/usr/src/lib/brand/sn1/Makefile.sn1
new file mode 100644
index 0000000000..1df9a2ad57
--- /dev/null
+++ b/usr/src/lib/brand/sn1/Makefile.sn1
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/brand/sn1/Makefile.sn1
+#
+# include global definitions
+
+BRAND = sn1
+
+include $(SRC)/lib/brand/Makefile.brand
+
diff --git a/usr/src/lib/brand/sn1/amd64/sn1_handler.s b/usr/src/lib/brand/sn1/amd64/sn1_handler.s
deleted file mode 100644
index f88c46d3b6..0000000000
--- a/usr/src/lib/brand/sn1/amd64/sn1_handler.s
+++ /dev/null
@@ -1,371 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/asm_linkage.h>
-#include <sn1_brand.h>
-
-#define RVAL2_FLAG 0x100
-
-#if defined(lint)
-
-void
-sn1_handler(void)
-{
-}
-
-#else /* lint */
- /*
- * %rax - syscall number
- * stack contains return address
- */
- ENTRY_NP(sn1_handler)
-
- pushq %rbp
- movq %rsp, %rbp
-
- /*
- * Look up the system call's entry in the sysent table below
- */
- pushq %rdx
- movq sn1_sysent_table@GOTPCREL(%rip), %rdx /* %rdx = sysent_table */
- shlq $4, %rax /* each entry is 16 bytes */
- addq %rdx, %rax /* %rax = sysent entry address */
- movq 8(%rax), %rdx /* get NARGS */
- testq $RVAL2_FLAG, %rdx /* does syscall have 2 return vals? */
- popq %rdx
- jz 1f
-
- /*
- * Two return syscall. We rely on none of these having either rval
- * be larger than 32 bits, and stick both into a single 64-bit
- * register. If that changes, we'll have to come up with a
- * different scheme.
- */
- call *(%rax)
- movq %rax, %rdx /* copy upper 32-bit rval into %rdx */
- shrq $32, %rdx /* move it to lower 32 bits */
- movl %eax, %eax
- jmp 2f
-
-1:
- call *(%rax) /* call per-syscall handler */
-
-2:
- /*
- * If %rax >= 0, it means the call completed successfully and %rax
- * is the proper return value. Otherwise, %rax contains -errno.
- * In the event of an error, we need to set the carry flag (which
- * is the kernel's indication of failure to libc) and set %rax to
- * the positive errno.
- */
- cmpq $0, %rax
- jge done
- negq %rax
- cmc
-
-done:
- movq %rbp, %rsp
- popq %rbp
- ret /* return to instr after syscall */
- SET_SIZE(sn1_handler)
-
- .section .data ,"aw"
- .globl sn1_sysent_table
- .align 8
-
-#define NOSYS \
- .quad sn1_unimpl; \
- .quad 0
-
-#define EMULATE(name, args) \
- .globl name; \
- .quad name; \
- .quad args
-
-sn1_sysent_table:
- .type sn1_sysent_table, @object
- .size sn1_sysent_table, 4096
- .align 8
-
- NOSYS /* 0 */
- NOSYS /* 1 */
- NOSYS /* 2 */
- NOSYS /* 3 */
- NOSYS /* 4 */
- NOSYS /* 5 */
- NOSYS /* 6 */
- NOSYS /* 7 */
- NOSYS /* 8 */
- NOSYS /* 9 */
- NOSYS /* 10 */
- NOSYS /* 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 */
- NOSYS /* 54 */
- NOSYS /* 55 */
- NOSYS /* 56 */
- NOSYS /* 57 */
- NOSYS /* 58 */
- NOSYS /* 59 */
- NOSYS /* 60 */
- NOSYS /* 61 */
- NOSYS /* 62 */
- NOSYS /* 63 */
- NOSYS /* 64 */
- NOSYS /* 65 */
- NOSYS /* 66 */
- NOSYS /* 67 */
- NOSYS /* 68 */
- NOSYS /* 69 */
- NOSYS /* 70 */
- NOSYS /* 71 */
- NOSYS /* 72 */
- NOSYS /* 73 */
- NOSYS /* 74 */
- NOSYS /* 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(sn1_uname, 1) /* 135 */
- NOSYS /* 136 */
- NOSYS /* 137 */
- NOSYS /* 138 */
- NOSYS /* 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 */
- NOSYS /* 159 */
- NOSYS /* 160 */
- NOSYS /* 161 */
- NOSYS /* 162 */
- NOSYS /* 163 */
- NOSYS /* 164 */
- NOSYS /* 165 */
- NOSYS /* 166 */
- NOSYS /* 167 */
- NOSYS /* 168 */
- NOSYS /* 169 */
- NOSYS /* 170 */
- NOSYS /* 171 */
- NOSYS /* 172 */
- NOSYS /* 173 */
- NOSYS /* 174 */
- NOSYS /* 175 */
- NOSYS /* 176 */
- NOSYS /* 177 */
- NOSYS /* 178 */
- NOSYS /* 179 */
- NOSYS /* 180 */
- NOSYS /* 181 */
- NOSYS /* 182 */
- NOSYS /* 183 */
- NOSYS /* 184 */
- NOSYS /* 185 */
- NOSYS /* 186 */
- NOSYS /* 187 */
- NOSYS /* 188 */
- NOSYS /* 189 */
- NOSYS /* 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 */
- NOSYS /* 223 */
- NOSYS /* 224 */
- NOSYS /* 225 */
- NOSYS /* 226 */
- NOSYS /* 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 */
-
-#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/common/sn1_brand.c b/usr/src/lib/brand/sn1/common/sn1_brand.c
deleted file mode 100644
index 088e0f6b9d..0000000000
--- a/usr/src/lib/brand/sn1/common/sn1_brand.c
+++ /dev/null
@@ -1,78 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <assert.h>
-#include <sn1_brand.h>
-#include <sys/syscall.h>
-#include <sys/utsname.h>
-#include <sys/inttypes.h>
-#include <sys/errno.h>
-#include <sys/systm.h>
-#include <sys/brand.h>
-
-extern int errno;
-
-int
-sn1_uname(uintptr_t p1)
-{
- struct utsname *un = (struct utsname *)p1;
- int rev, err;
-
- err = syscall(SYS_uname + 1024, p1);
- if (err >= 0) {
- rev = atoi(&un->release[2]);
- assert(rev >= 10);
- (void) sprintf(un->release, "5.%d", rev - 1);
- } else {
- err = -errno;
- }
- return (err);
-}
-
-int
-sn1_unimpl(uintptr_t p1)
-{
- (void) fprintf(stderr,
- "unimplemented syscall (%d) in emulation library\n", (int)p1);
- return (-EINVAL);
-}
-
-#pragma init(sn1_init)
-
-int
-sn1_init()
-{
- if (syscall(SYS_brand, B_REGISTER, (void *)sn1_handler)) {
- perror("failed to brand the process");
- return (1);
- }
-
- return (0);
-}
diff --git a/usr/src/lib/brand/sn1/common/sn1_brand.h b/usr/src/lib/brand/sn1/common/sn1_brand.h
deleted file mode 100644
index 9d341cf195..0000000000
--- a/usr/src/lib/brand/sn1/common/sn1_brand.h
+++ /dev/null
@@ -1,47 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SN1_BRAND_H
-#define _SN1_BRAND_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define NSYSCALL 256 /* number of system calls */
-
-#ifndef _ASM
-
-extern void sn1_handler(void);
-
-#endif /* _ASM */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SN1_BRAND_H */
diff --git a/usr/src/lib/brand/sn1/i386/sn1_handler.s b/usr/src/lib/brand/sn1/i386/sn1_handler.s
deleted file mode 100644
index decc218412..0000000000
--- a/usr/src/lib/brand/sn1/i386/sn1_handler.s
+++ /dev/null
@@ -1,390 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/asm_linkage.h>
-#include <sn1_brand.h>
-
-#define PIC_SETUP(r) \
- call 9f; \
-9: \
- popl r; \
- addl $_GLOBAL_OFFSET_TABLE_ + [. - 9b], r
-
-#if defined(lint)
-
-void
-sn1_handler(void)
-{
-}
-
-#else /* lint */
- /*
- * %eax - syscall number
- * stack contains return address
- */
- ENTRY_NP(sn1_handler)
- pushl %ebp
- movl %esp, %ebp
-
- /* Save scratch registers */
- pushl %edi
- pushl %esi
- pushl %ecx
- pushl %ebx
-
- /*
- * Look up the system call's entry in the sysent table below, then
- * jump to the address of the emulation routine for that call.
- */
- PIC_SETUP(%ebx)
- movl sn1_sysent_table@GOT(%ebx), %edx /* %edx = sysent_table */
- shll $3, %eax /* each entry is 8 bytes */
- add %eax, %edx /* %edx = sysent entry address */
-
- /*
- * Copy the arguments to the system call into the stack frame
- * for the emulating routine.
- * Note: we always save room on the stack for 8 arguments. This is
- * because when we come back from the system call routine, we have
- * lost our pointer to the sysent structure and no longer know
- * precisely know how much stack space to free up.
- */
- movl %esp, %esi
- addl $28, %esi /* start of args */
- movl 4(%edx), %ecx /* number of args */
- subl $32, %esp /* make room for copies */
- movl %esp, %edi /* start of arg copy area */
- rep; smovl /* copy args */
-
- call *(%edx) /* call per-syscall handler */
-
- addl $32, %esp /* free up the stack space used for args. */
-
- /*
- * If %eax >= 0, it means the call completed successfully and %eax
- * is the proper return value. Otherwise, %eax contains -errno.
- * In the event of an error, we need to set the carry flag (which
- * is the kernel's indication of failure to libc) and set %eax to
- * the positive errno.
- *
- * Unlike the amd64, v8, and v9 brands, we don't have to do
- * anything special for two rval system calls. By returning a
- * longlong_t, the emulation routine puts the proper values into
- * %eax and %edx for us.
- */
- cmpl $0, %eax
- jge done
- negl %eax
- cmc
-
-done:
- popl %ebx /* restore scratch registers */
- popl %ecx
- popl %esi
- popl %edi
-
- movl %ebp, %esp
- popl %ebp
- ret /* return to instr after sysenter */
- SET_SIZE(sn1_handler)
-
- .section .data ,"aw"
- .globl sn1_sysent_table
- .align 4
-
-#define NOSYS \
- .long sn1_unimpl; \
- .long 0
-
-#define EMULATE(name, args) \
- .globl name; \
- .long name; \
- .long args
-
-sn1_sysent_table:
- .type sn1_sysent_table, @object
- .size sn1_sysent_table, 2048
- .align 4
-
- NOSYS /* 0 */
- NOSYS /* 1 */
- NOSYS /* 2 */
- NOSYS /* 3 */
- NOSYS /* 4 */
- NOSYS /* 5 */
- NOSYS /* 6 */
- NOSYS /* 7 */
- NOSYS /* 8 */
- NOSYS /* 9 */
- NOSYS /* 10 */
- NOSYS /* 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 */
- NOSYS /* 54 */
- NOSYS /* 55 */
- NOSYS /* 56 */
- NOSYS /* 57 */
- NOSYS /* 58 */
- NOSYS /* 59 */
- NOSYS /* 60 */
- NOSYS /* 61 */
- NOSYS /* 62 */
- NOSYS /* 63 */
- NOSYS /* 64 */
- NOSYS /* 65 */
- NOSYS /* 66 */
- NOSYS /* 67 */
- NOSYS /* 68 */
- NOSYS /* 69 */
- NOSYS /* 70 */
- NOSYS /* 71 */
- NOSYS /* 72 */
- NOSYS /* 73 */
- NOSYS /* 74 */
- NOSYS /* 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(sn1_uname, 1) /* 135 */
- NOSYS /* 136 */
- NOSYS /* 137 */
- NOSYS /* 138 */
- NOSYS /* 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 */
- NOSYS /* 159 */
- NOSYS /* 160 */
- NOSYS /* 161 */
- NOSYS /* 162 */
- NOSYS /* 163 */
- NOSYS /* 164 */
- NOSYS /* 165 */
- NOSYS /* 166 */
- NOSYS /* 167 */
- NOSYS /* 168 */
- NOSYS /* 169 */
- NOSYS /* 170 */
- NOSYS /* 171 */
- NOSYS /* 172 */
- NOSYS /* 173 */
- NOSYS /* 174 */
- NOSYS /* 175 */
- NOSYS /* 176 */
- NOSYS /* 177 */
- NOSYS /* 178 */
- NOSYS /* 179 */
- NOSYS /* 180 */
- NOSYS /* 181 */
- NOSYS /* 182 */
- NOSYS /* 183 */
- NOSYS /* 184 */
- NOSYS /* 185 */
- NOSYS /* 186 */
- NOSYS /* 187 */
- NOSYS /* 188 */
- NOSYS /* 189 */
- NOSYS /* 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 */
- NOSYS /* 223 */
- NOSYS /* 224 */
- NOSYS /* 225 */
- NOSYS /* 226 */
- NOSYS /* 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 */
-
-#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/librtld_db/Makefile b/usr/src/lib/brand/sn1/librtld_db/Makefile
new file mode 100644
index 0000000000..c6af8446a7
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/Makefile
@@ -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 2008 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:
diff --git a/usr/src/lib/brand/sn1/librtld_db/Makefile.com b/usr/src/lib/brand/sn1/librtld_db/Makefile.com
new file mode 100644
index 0000000000..fa245f5196
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/Makefile.com
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY = sn1_librtld_db.a
+VERS = .1
+COBJS = sn1_librtld_db.o
+OBJECTS = $(COBJS) $(COBJS64)
+
+include $(SRC)/lib/Makefile.lib
+include ../../Makefile.sn1
+
+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/sn1 \
+ -I../../../../../cmd/sgs/librtld_db/common \
+ -I../../../../../cmd/sgs/include \
+ -I../../../../../cmd/sgs/include/$(MACH)
+
+ROOTLIBDIR = $(ROOT)/usr/lib/brand/sn1
+ROOTLIBDIR64 = $(ROOT)/usr/lib/brand/sn1/$(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
diff --git a/usr/src/lib/brand/sn1/amd64/Makefile b/usr/src/lib/brand/sn1/librtld_db/amd64/Makefile
index 98897d9ba8..d1b2579c29 100644
--- a/usr/src/lib/brand/sn1/amd64/Makefile
+++ b/usr/src/lib/brand/sn1/librtld_db/amd64/Makefile
@@ -19,18 +19,16 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# lib/brand/sn1/amd64/Makefile
-ISASRCDIR=.
+COBJS64 = sn1_librtld_db64.o
include ../Makefile.com
-include ../../../Makefile.lib.64
+include $(SRC)/lib/Makefile.lib.64
-CPPFLAGS += -D_SYSCALL32
+CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB)
+DYNFLAGS += -M../common/mapfile-vers.64
install: all $(ROOTLIBS64)
diff --git a/usr/src/lib/brand/sn1/librtld_db/amd64/mapfile-vers b/usr/src/lib/brand/sn1/librtld_db/amd64/mapfile-vers
new file mode 100644
index 0000000000..bb30156339
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/amd64/mapfile-vers
@@ -0,0 +1,29 @@
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+SUNWprivate_1.1 {
+ global:
+ rtld_db_brand_ops64;
+};
diff --git a/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers
new file mode 100644
index 0000000000..d065527a42
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+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;
+};
diff --git a/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers.64 b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers.64
new file mode 100644
index 0000000000..bb30156339
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers.64
@@ -0,0 +1,29 @@
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+SUNWprivate_1.1 {
+ global:
+ rtld_db_brand_ops64;
+};
diff --git a/usr/src/lib/brand/sn1/librtld_db/common/sn1_librtld_db.c b/usr/src/lib/brand/sn1/librtld_db/common/sn1_librtld_db.c
new file mode 100644
index 0000000000..c4678b78ab
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/common/sn1_librtld_db.c
@@ -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 2008 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 <sn1_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 sn1_ldb_init32 sn1_ldb_init64
+#define sn1_ldb_fini32 sn1_ldb_fini64
+#define sn1_ldb_loadobj_iter32 sn1_ldb_loadobj_iter64
+#define sn1_ldb_get_dyns32 sn1_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
+sn1_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_SN1_LDDATA. So we'll just look that up here.
+ */
+/*ARGSUSED*/
+static rd_helper_data_t
+sn1_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("sn1_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 = sn1_ldb_getauxval32(php, AT_SUN_BRAND_SN1_LDDATA);
+ if (lddata_addr == (uint32_t)-1) {
+ ps_plog("sn1_ldb_init: no LDDATA found in aux vector");
+ return (NULL);
+ }
+ ps_plog("sn1_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("sn1_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("sn1_ldb_init: can't find valid r_debug data");
+ free(rap_new);
+ return (NULL);
+ }
+
+ ps_plog("sn1_ldb_init: finished, helper_data=0x%p", rap_new);
+ return ((rd_helper_data_t)rap_new);
+}
+
+static void
+sn1_ldb_fini32(rd_helper_data_t rhd)
+{
+ struct rd_agent *rap = (struct rd_agent *)rhd;
+ ps_plog("lx_ldb_fini: cleaning up sn1 helper");
+ free(rap);
+}
+
+/*ARGSUSED*/
+static int
+sn1_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("sn1_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("sn1_ldb_loadobj_iter: finished, err = %d", err);
+ return (err);
+}
+
+/*ARGSUSED*/
+static rd_err_e
+sn1_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("sn1_ldb_get_dyns(helper_data=0x%p)", rhd);
+ err = _rd_get_dyns32(rap, addr, (Elf32_Dyn **)dynpp, dynpp_sz);
+ ps_plog("sn1_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,
+ sn1_ldb_init32,
+ sn1_ldb_fini32,
+ sn1_ldb_loadobj_iter32,
+ sn1_ldb_get_dyns32
+};
diff --git a/usr/src/lib/brand/sn1/i386/Makefile b/usr/src/lib/brand/sn1/librtld_db/i386/Makefile
index 9f1797b292..db4ae0937b 100644
--- a/usr/src/lib/brand/sn1/i386/Makefile
+++ b/usr/src/lib/brand/sn1/librtld_db/i386/Makefile
@@ -19,17 +19,12 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# lib/brand/sn1/i386/Makefile
-
-ISASRCDIR=.
-
-ASFLAGS += $(AS_PICFLAGS) -P -D_ASM
include ../Makefile.com
+CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB)
+
install: all $(ROOTLIBS)
diff --git a/usr/src/lib/brand/sn1/sparc/Makefile b/usr/src/lib/brand/sn1/librtld_db/sparc/Makefile
index 0b13e01a82..db4ae0937b 100644
--- a/usr/src/lib/brand/sn1/sparc/Makefile
+++ b/usr/src/lib/brand/sn1/librtld_db/sparc/Makefile
@@ -19,17 +19,12 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# lib/brand/sn1/sparc/Makefile
-
-ISASRCDIR=.
include ../Makefile.com
-ASFLAGS += -xarch=v8plus ${AS_PICFLAGS}
+CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB)
install: all $(ROOTLIBS)
diff --git a/usr/src/lib/brand/sn1/sparcv9/Makefile b/usr/src/lib/brand/sn1/librtld_db/sparcv9/Makefile
index 71d84e94ae..d1b2579c29 100644
--- a/usr/src/lib/brand/sn1/sparcv9/Makefile
+++ b/usr/src/lib/brand/sn1/librtld_db/sparcv9/Makefile
@@ -19,18 +19,16 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# lib/brand/sn1/sparcv9/Makefile
-
-ISASRCDIR=../sparc
-ASFLAGS_$(CURTYPE) += ${AS_PICFLAGS}
+COBJS64 = sn1_librtld_db64.o
include ../Makefile.com
-include ../../../Makefile.lib.64
+include $(SRC)/lib/Makefile.lib.64
+
+CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB)
+DYNFLAGS += -M../common/mapfile-vers.64
install: all $(ROOTLIBS64)
diff --git a/usr/src/lib/brand/sn1/librtld_db/sparcv9/mapfile-vers b/usr/src/lib/brand/sn1/librtld_db/sparcv9/mapfile-vers
new file mode 100644
index 0000000000..bb30156339
--- /dev/null
+++ b/usr/src/lib/brand/sn1/librtld_db/sparcv9/mapfile-vers
@@ -0,0 +1,29 @@
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+SUNWprivate_1.1 {
+ global:
+ rtld_db_brand_ops64;
+};
diff --git a/usr/src/lib/brand/sn1/sn1_brand/Makefile b/usr/src/lib/brand/sn1/sn1_brand/Makefile
new file mode 100644
index 0000000000..2768bd2175
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../../../Makefile.lib
+
+default: all
+
+SUBDIRS = $(MACH) $(VARIANT_SUBDIRS)
+$(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 _msg: $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/brand/sn1/sn1_brand/Makefile.com b/usr/src/lib/brand/sn1/sn1_brand/Makefile.com
new file mode 100644
index 0000000000..4059dff444
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile.com
@@ -0,0 +1,105 @@
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY = sn1_brand.a
+VERS = .1
+COBJS = sn1_brand.o
+ASOBJS = sn1_crt.o sn1_handler.o sn1_runexe.o
+OFFSETS_SRC = ../common/offsets.in
+OFFSETS_H = assym.h
+OBJECTS = $(COBJS) $(ASOBJS)
+CLOBBERFILES += $(OFFSETS_H)
+
+include ../../Makefile.sn1
+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
+# explicily specify an interpreter for the brand emulation library.
+# Normally this would be the native linker, /.SUNWnative/usr/lib/ld.so.1
+# or /.SUNWnative/usr/lib/64/ld.so.1.
+#
+# 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().
+#
+# XXX: Note that we also set the runtime path for the emulation library to
+# point into /.SUNWnative/. This ensures that our brand library get's the
+# native versions of any libraries it needs. Unfortunatly this is a total
+# hack since it doesn't work for suid binaries. What we really need to do
+# is enhance the linker so that when it's running on a brand linkmap it
+# looks for all libraries in the brands "native" directory (for both
+# regular and suid binaries).
+#
+NATIVE_DIR = /.SUNWnative
+CPPFLAGS += -D_REENTRANT -U_ASM -I. -I../sys -I$(UTSBASE)/common/brand/sn1
+CFLAGS += $(CCVERBOSE)
+ASFLAGS = -P $(ASFLAGS_$(CURTYPE)) -D_ASM -I. -I../sys
+DYNFLAGS += $(DYNFLAGS_$(CLASS))
+DYNFLAGS += $(BLOCAL) $(ZNOVERSION) -Wl,-e_start
+#DYNFLAGS += -R$(NATIVE_DIR)/lib -R$(NATIVE_DIR)/usr/lib
+LDLIBS += -lc -lmapmalloc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+#
+# build the offset header before trying to compile any files. (it's included
+# by sn1_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
diff --git a/usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile b/usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile
new file mode 100644
index 0000000000..e82bb23093
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/brand/sn1/amd64/Makefile
+
+ISASRCDIR = .
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+#
+# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter
+#
+DYNFLAGS += -Wl,-I$(NATIVE_DIR)/usr/lib/64/ld.so.1
+CPPFLAGS += -D_SYSCALL32
+
+CLEANFILES += $(DYNLIB)
+CLOBBERFILES += $(ROOTLIBS64)
+
+install: all $(ROOTLIBS64)
diff --git a/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_crt.s b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_crt.s
new file mode 100644
index 0000000000..48dbe8e104
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_crt.s
@@ -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 2008 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:
+ * sn1_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 sn1_init
+
+ /*NOTREACHED*/
+ SET_SIZE(_start)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s
new file mode 100644
index 0000000000..f899a08eae
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+void
+sn1_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(sn1_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 sn1_misc.h.
+ */
+ subq $EH_LOCALS_SIZE, %rsp
+
+ /* Look up the system call's entry in the sysent table */
+ movq sn1_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(sn1_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(sn1_handler)
+
+
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_runexe.s b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_runexe.s
new file mode 100644
index 0000000000..4798d4fe87
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_runexe.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+sn1_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(sn1_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(sn1_runexe)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/common/mapfile-vers b/usr/src/lib/brand/sn1/sn1_brand/common/mapfile-vers
index 9ba563a2cb..3567a27f04 100644
--- a/usr/src/lib/brand/sn1/common/mapfile-vers
+++ b/usr/src/lib/brand/sn1/sn1_brand/common/mapfile-vers
@@ -20,10 +20,9 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
#
# Scope everything local -- our .init section is our only public interface.
diff --git a/usr/src/lib/brand/sn1/sn1_brand/common/offsets.in b/usr/src/lib/brand/sn1/sn1_brand/common/offsets.in
new file mode 100644
index 0000000000..2897555874
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/common/offsets.in
@@ -0,0 +1,35 @@
+\
+\ Copyright 2008 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
diff --git a/usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c b/usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c
new file mode 100644
index 0000000000..775d8144c5
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c
@@ -0,0 +1,758 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.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 <sn1_brand.h>
+#include <sn1_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 sn1_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 sn1_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.
+ *
+ *
+ * *** 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 (sn1_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.
+ *
+ *
+ * *** sn1 brand emulation scope considerations
+ *
+ * One of the differences between the lx brand and the s8 and s9
+ * brands, is that the s8 and s9 brands only interpose on syscalls
+ * that need some kind of emulation, where as the lx brand interposes
+ * on _all_ system calls. Lx branded system calls that don't need
+ * any emulation are then redirected back to the kernel from the
+ * userland library via the IN_KERNEL_SYSCALL macro. The lx-syscall
+ * dtrace provider depends on this behavior.
+ *
+ * Given that the sn1 brand exists for testing purposes, it should
+ * eventually be enhanced to redirect all system calls through the
+ * brand emulation library. This will ensure the maximum testing
+ * exposure for the brandz infrastructure. Some other options to
+ * consider for improving brandz test exposure are:
+ * - Folding the sn1 brand into the native brand and only enabling
+ * it on DEBUG builds.
+ * - Modifying the zones test suite to use sn1 branded zones by default,
+ * any adapting functional test harnesses to use sn1 branded zones
+ * by default instead of native zones.
+ */
+
+#define EMULATE(cb, args) { (sysent_cb_t)(cb), (args) }
+#define NOSYS EMULATE(sn1_unimpl, (0 | RV_DEFAULT))
+
+typedef long (*sysent_cb_t)();
+typedef struct sn1_sysent_table {
+ sysent_cb_t st_callc;
+ uintptr_t st_args;
+} sn1_sysent_table_t;
+sn1_sysent_table_t sn1_sysent_table[];
+
+/*LINTED: static unused*/
+static volatile int sn1_abort_err;
+/*LINTED: static unused*/
+static volatile const char *sn1_abort_msg;
+/*LINTED: static unused*/
+static volatile const char *sn1_abort_file;
+/*LINTED: static unused*/
+static volatile int sn1_abort_line;
+
+extern int errno;
+
+/*ARGSUSED*/
+void
+_sn1_abort(int err, const char *msg, const char *file, int line)
+{
+ sysret_t rval;
+
+ /* Save the error message into convenient globals */
+ sn1_abort_err = err;
+ sn1_abort_msg = msg;
+ sn1_abort_file = file;
+ sn1_abort_line = line;
+
+ /* kill ourselves */
+ abort();
+
+ /* If abort() didn't work, try something stronger. */
+ (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
+}
+
+/*
+ * 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
+sn1_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
+sn1_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)
+{
+ sn1_sysent_table_t *sst = &(sn1_sysent_table[code]);
+
+ sn1_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));
+ }
+ sn1_abort(0, "invalid entry in sn1_sysent_table");
+ return (EINVAL);
+}
+#endif /* __sparc && !__sparcv9 */
+
+static long
+sn1_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]);
+ sn1_assert(rev >= 10);
+ (void) sprintf(un.release, "5.%d", rev - 1);
+
+ if (uucopy(&un, unp, sizeof (un)) != 0)
+ return (EFAULT);
+ return (0);
+}
+
+/*
+ * Close a libc file handle, but don't actually close the underlying
+ * file descriptor.
+ */
+static void
+sn1_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
+sn1_init(int argc, char *argv[], char *envp[])
+{
+ sysret_t rval;
+ sn1_brand_reg_t reg;
+ sn1_elf_data_t sed;
+ auxv_t *ap;
+ uintptr_t *p;
+ int i, err;
+
+ /* Sanity check our translation table return value codes */
+ for (i = 0; i < NSYSCALL; i++) {
+ sn1_sysent_table_t *est = &(sn1_sysent_table[i]);
+ sn1_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.
+ */
+ sn1_close_fh(stdin);
+ sn1_close_fh(stdout);
+ sn1_close_fh(stderr);
+
+ /*
+ * 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 = SN1_VERSION;
+ reg.sbr_handler = (caddr_t)sn1_handler;
+ if ((err = __systemcall(&rval, SYS_brand, B_REGISTER, &reg)) != 0) {
+ sn1_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) {
+ sn1_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 sn1_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;
+ }
+ }
+
+ sn1_runexe(argv, sed.sed_ldentry);
+ /*NOTREACHED*/
+ sn1_abort(0, "sn1_runexe() returned");
+ return (-1);
+}
+
+#define IN_KERNEL_SYSCALL(name, num) \
+static long \
+sn1_##name(sysret_t *rv, \
+ uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, \
+ uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7) \
+{ \
+ return (__systemcall(rv, num + 1024, \
+ a0, a1, a2, a3, a4, a5, a6, a7)); \
+}
+
+/*
+ * These are branded system calls, which have been redirected to this
+ * userland emulation library, and are emulated by passing them strait
+ * on to the kernel as native system calls.
+ */
+IN_KERNEL_SYSCALL(read, SYS_read) /* 3 */
+IN_KERNEL_SYSCALL(write, SYS_write) /* 4 */
+IN_KERNEL_SYSCALL(wait, SYS_wait) /* 7 */
+IN_KERNEL_SYSCALL(time, SYS_time) /* 13 */
+IN_KERNEL_SYSCALL(getpid, SYS_getpid) /* 20 */
+IN_KERNEL_SYSCALL(mount, SYS_mount) /* 21 */
+IN_KERNEL_SYSCALL(getuid, SYS_getuid) /* 24 */
+IN_KERNEL_SYSCALL(times, SYS_times) /* 43 */
+IN_KERNEL_SYSCALL(getgid, SYS_getgid) /* 47 */
+IN_KERNEL_SYSCALL(utssys, SYS_utssys) /* 57 */
+IN_KERNEL_SYSCALL(readlink, SYS_readlink) /* 90 */
+
+/*
+ * This table must have at least NSYSCALL entries in it.
+ *
+ * The second parameter of each entry in the sn1_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.
+ */
+sn1_sysent_table_t sn1_sysent_table[] = {
+#if defined(__sparc) && !defined(__sparcv9)
+ EMULATE(sn1_indir, 9 | RV_64RVAL), /* 0 */
+#else /* !__sparc || __sparcv9 */
+ NOSYS, /* 0 */
+#endif /* !__sparc || __sparcv9 */
+ NOSYS, /* 1 */
+ NOSYS, /* 2 */
+ EMULATE(sn1_read, 3 | RV_DEFAULT), /* 3 */
+ EMULATE(sn1_write, 3 | RV_DEFAULT), /* 4 */
+ NOSYS, /* 5 */
+ NOSYS, /* 6 */
+ EMULATE(sn1_wait, 0 | RV_32RVAL2), /* 7 */
+ NOSYS, /* 8 */
+ NOSYS, /* 9 */
+ NOSYS, /* 10 */
+ NOSYS, /* 11 */
+ NOSYS, /* 12 */
+ EMULATE(sn1_time, 0 | RV_DEFAULT), /* 13 */
+ NOSYS, /* 14 */
+ NOSYS, /* 15 */
+ NOSYS, /* 16 */
+ NOSYS, /* 17 */
+ NOSYS, /* 18 */
+ NOSYS, /* 19 */
+ EMULATE(sn1_getpid, 0 | RV_32RVAL2), /* 20 */
+ EMULATE(sn1_mount, 8 | RV_DEFAULT), /* 21 */
+ NOSYS, /* 22 */
+ NOSYS, /* 23 */
+ EMULATE(sn1_getuid, 0 | RV_32RVAL2), /* 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 */
+ EMULATE(sn1_times, 1 | RV_DEFAULT), /* 43 */
+ NOSYS, /* 44 */
+ NOSYS, /* 45 */
+ NOSYS, /* 46 */
+ EMULATE(sn1_getgid, 0 | RV_32RVAL2), /* 47 */
+ NOSYS, /* 48 */
+ NOSYS, /* 49 */
+ NOSYS, /* 50 */
+ NOSYS, /* 51 */
+ NOSYS, /* 52 */
+ NOSYS, /* 53 */
+ NOSYS, /* 54 */
+ NOSYS, /* 55 */
+ NOSYS, /* 56 */
+ EMULATE(sn1_utssys, 4 | RV_32RVAL2), /* 57 */
+ NOSYS, /* 58 */
+ NOSYS, /* 59 */
+ NOSYS, /* 60 */
+ NOSYS, /* 61 */
+ NOSYS, /* 62 */
+ NOSYS, /* 63 */
+ NOSYS, /* 64 */
+ NOSYS, /* 65 */
+ NOSYS, /* 66 */
+ NOSYS, /* 67 */
+ NOSYS, /* 68 */
+ NOSYS, /* 69 */
+ NOSYS, /* 70 */
+ NOSYS, /* 71 */
+ NOSYS, /* 72 */
+ NOSYS, /* 73 */
+ NOSYS, /* 74 */
+ NOSYS, /* 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 */
+ EMULATE(sn1_readlink, 3 | RV_DEFAULT), /* 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(sn1_uname, 1 | RV_DEFAULT), /* 135 */
+ NOSYS, /* 136 */
+ NOSYS, /* 137 */
+ NOSYS, /* 138 */
+ NOSYS, /* 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 */
+ NOSYS, /* 159 */
+ NOSYS, /* 160 */
+ NOSYS, /* 161 */
+ NOSYS, /* 162 */
+ NOSYS, /* 163 */
+ NOSYS, /* 164 */
+ NOSYS, /* 165 */
+ NOSYS, /* 166 */
+ NOSYS, /* 167 */
+ NOSYS, /* 168 */
+ NOSYS, /* 169 */
+ NOSYS, /* 170 */
+ NOSYS, /* 171 */
+ NOSYS, /* 172 */
+ NOSYS, /* 173 */
+ NOSYS, /* 174 */
+ NOSYS, /* 175 */
+ NOSYS, /* 176 */
+ NOSYS, /* 177 */
+ NOSYS, /* 178 */
+ NOSYS, /* 179 */
+ NOSYS, /* 180 */
+ NOSYS, /* 181 */
+ NOSYS, /* 182 */
+ NOSYS, /* 183 */
+ NOSYS, /* 184 */
+ NOSYS, /* 185 */
+ NOSYS, /* 186 */
+ NOSYS, /* 187 */
+ NOSYS, /* 188 */
+ NOSYS, /* 189 */
+ NOSYS, /* 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 */
+ NOSYS, /* 223 */
+ NOSYS, /* 224 */
+ NOSYS, /* 225 */
+ NOSYS, /* 226 */
+ NOSYS, /* 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 */
+};
diff --git a/usr/src/lib/brand/sn1/sn1_brand/i386/Makefile b/usr/src/lib/brand/sn1/sn1_brand/i386/Makefile
new file mode 100644
index 0000000000..e5f9fdb455
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/i386/Makefile
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/brand/sn1/i386/Makefile
+
+ISASRCDIR = .
+
+include ../Makefile.com
+
+#
+# see ../Makefile.com for why we explicity make ld.so.1 our interpreter
+#
+DYNFLAGS += -Wl,-I$(NATIVE_DIR)/usr/lib/ld.so.1
+
+CLEANFILES += $(DYNLIB)
+CLOBBERFILES += $(ROOTLIBS)
+
+install: all $(ROOTLIBS)
diff --git a/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_crt.s b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_crt.s
new file mode 100644
index 0000000000..f4c6e8d408
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_crt.s
@@ -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 2008 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:
+ * sn1_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 sn1_init
+
+ /*NOTREACHED*/
+ SET_SIZE(_start)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s
new file mode 100644
index 0000000000..abace2aec8
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+void
+sn1_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(sn1_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)
+ movl %cs, EH_LOCALS_GREG(CS)(%ebp)
+ movl %ds, EH_LOCALS_GREG(DS)(%ebp)
+ movl %es, EH_LOCALS_GREG(ES)(%ebp)
+ movl %fs, EH_LOCALS_GREG(FS)(%ebp)
+ movl %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 sn1_misc.h.
+ */
+ subl $EH_LOCALS_SIZE, %esp
+
+ /* Look up the system call's entry in the sysent table */
+ PIC_SETUP(%ecx)
+ movl sn1_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(sn1_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(sn1_handler)
+
+
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_runexe.s b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_runexe.s
new file mode 100644
index 0000000000..8e9eec3f6d
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_runexe.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+sn1_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(sn1_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(sn1_runexe)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile b/usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile
new file mode 100644
index 0000000000..1f2a6c7f89
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/brand/sn1/sparc/Makefile
+
+ISASRCDIR = .
+
+include ../Makefile.com
+
+#
+# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter
+#
+DYNFLAGS += -Wl,-I$(NATIVE_DIR)/usr/lib/ld.so.1
+ASFLAGS += -xarch=v8plus ${AS_PICFLAGS}
+
+CLEANFILES += $(DYNLIB)
+CLOBBERFILES += $(ROOTLIBS)
+
+install: all $(ROOTLIBS)
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_crt.s b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_crt.s
new file mode 100644
index 0000000000..e4931d67b3
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_crt.s
@@ -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 2008 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:
+ * sn1_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 sn1_init
+ nop
+
+ /*NOTREACHED*/
+ SET_SIZE(_start)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s
new file mode 100644
index 0000000000..b96782c037
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+void
+sn1_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(sn1_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 sn1_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, sn1_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(sn1_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(sn1_handler)
+
+
+#endif /* !lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_runexe.s b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_runexe.s
new file mode 100644
index 0000000000..67dcb8895d
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_runexe.s
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/asm_linkage.h>
+#include <sn1_misc.h>
+
+#if defined(lint)
+
+/*ARGSUSED*/
+void
+sn1_runexe(void *argv, ulong_t entry)
+{
+}
+
+#else /* lint */
+ .section ".text"
+ ENTRY_NP(sn1_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(sn1_runexe)
+#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile b/usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile
new file mode 100644
index 0000000000..90c9270c00
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile
@@ -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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/brand/sn1/sparcv9/Makefile
+
+ISASRCDIR = ../sparc
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+#
+# see ../Makefile.com for why we explicity make ld.so.1 our interpreter
+#
+DYNFLAGS += -Wl,-I$(NATIVE_DIR)/usr/lib/64/ld.so.1
+ASFLAGS_$(CURTYPE) += ${AS_PICFLAGS}
+
+CLEANFILES += $(DYNLIB)
+CLOBBERFILES += $(ROOTLIBS64)
+
+install: all $(ROOTLIBS64)
diff --git a/usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h b/usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h
new file mode 100644
index 0000000000..0ea4313008
--- /dev/null
+++ b/usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h
@@ -0,0 +1,173 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SN1_MISC_H
+#define _SN1_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 "sn1_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 sn1_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/sn1_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 sn1_assert(ex) (void)((ex) || \
+ (_sn1_abort(0, #ex, __FILE__, __LINE__), 0))
+#define sn1_abort(err, msg) _sn1_abort((err), (msg), __FILE__, __LINE__)
+
+/*
+ * From sn1_runexe.s
+ */
+extern void sn1_runexe(void *, ulong_t);
+
+/*
+ * From sn1_handler.s
+ */
+extern void sn1_handler(void);
+extern void sn1_error(void);
+extern void sn1_success(void);
+
+/*
+ * From sn1_brand.c
+ */
+extern void _sn1_abort(int, const char *, const char *, int);
+
+#endif /* !_ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SN1_MISC_H */
diff --git a/usr/src/lib/brand/sn1/sparc/sn1_handler.s b/usr/src/lib/brand/sn1/sparc/sn1_handler.s
deleted file mode 100644
index 114a28b863..0000000000
--- a/usr/src/lib/brand/sn1/sparc/sn1_handler.s
+++ /dev/null
@@ -1,421 +0,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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/asm_linkage.h>
-#include <sn1_brand.h>
-
-#define RVAL2_FLAG 0x100
-
-#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.
- */
-#ifdef __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
-#define GET_SYM_ADDR(r1, r2, name) \
- PIC_SETUP(r1); \
- ld [r1 + name], r1
-#endif
-
-#if defined(lint)
-
-void
-sn1_handler(void)
-{
-}
-
-#else /* lint */
-
- .section ".text"
-
- /*
- * When we get here, %g1 should contain the system call and
- * %g6 should contain the address immediately after the trap
- * instruction.
- */
- ENTRY_NP(sn1_handler)
- save %sp, -SA(MINFRAME), %sp
-
- ! We grabbed a new window, so copy the args for the target routine.
- mov %i0, %o0
- mov %i1, %o1
- mov %i2, %o2
- mov %i3, %o3
- mov %i4, %o4
- mov %i5, %o5
-
- /*
- * Find the base address of the jump table, index into it based
- * on the system call number, and extract the address of the proper
- * emulation routine.
- */
- sll %g1, (1 + CLONGSHIFT), %l1 /* Each entry has 2 longs */
- GET_SYM_ADDR(%l2, %l0, sn1_sysent_table)
- add %l1, %l2, %l3 /* index to proper entry */
- ldn [%l3 + CPTRSIZE], %l4 /* save NARGS */
- ldn [%l3], %l3 /* emulation address */
- call %l3
- nop
-
- /*
- * Check for two-return syscall.
- */
- andcc %l4, RVAL2_FLAG, %g0
- be 1f
- nop
-#ifdef __sparcv9
- /*
- * In 64-bit code, the syscall emulation routine returns the values
- * in a single 64-bit register. We split it into two 32-bit values.
- */
- srlx %o0, 32, %o1
- srl %o0, 0, %o0
- mov %o1, %i1
-#else
- /*
- * In 32-bit code, the syscall emulation routine returns the values
- * in two registers - just the wrong ones.
- */
- mov %o0, %i1
- mov %o1, %o0
-#endif
-
-1:
- /*
- * If %o0 >= 0, it means the call completed successfully and %o0 is
- * the proper return value. Otherwise, %o0 contains -errno. In
- * the event of an error, we need to set the carry flag (which is
- * the kernel's indication of failure to libc) and set %o0 to the
- * positive errno.
- */
- brgez %o0, 2f /* %o0 >= 0, so we're done. */
- addcc %g0, %g0, %g0 ! psr &= ~C
- neg %o0
- subcc %g0, 1, %g0 ! psr |= C
-2:
- mov %o0, %i0
- restore
- jmp %g6
- nop
- SET_SIZE(sn1_handler)
-
- .section ".data",#alloc,#write
- .global sn1_sysent_table
- .align CLONGSIZE
-
- .global sn1_unimpl
-#ifdef __sparcv9
-#define WORD .xword
-#else
-#define WORD .word
-#endif
-
-#define NOSYS \
- WORD sn1_unimpl ;\
- WORD 0
-
-#define EMULATE(name, args) \
- .global name ;\
- WORD name ;\
- WORD args
-
-sn1_sysent_table:
- .type sn1_sysent_table, #object
- .size sn1_sysent_table, (2 * 256 * CLONGSIZE)
- .align CLONGSIZE
- NOSYS /* 0 */
- NOSYS /* 1 */
- NOSYS /* 2 */
- NOSYS /* 3 */
- NOSYS /* 4 */
- NOSYS /* 5 */
- NOSYS /* 6 */
- NOSYS /* 7 */
- NOSYS /* 8 */
- NOSYS /* 9 */
- NOSYS /* 10 */
- NOSYS /* 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 */
- NOSYS /* 54 */
- NOSYS /* 55 */
- NOSYS /* 56 */
- NOSYS /* 57 */
- NOSYS /* 58 */
- NOSYS /* 59 */
- NOSYS /* 60 */
- NOSYS /* 61 */
- NOSYS /* 62 */
- NOSYS /* 63 */
- NOSYS /* 64 */
- NOSYS /* 65 */
- NOSYS /* 66 */
- NOSYS /* 67 */
- NOSYS /* 68 */
- NOSYS /* 69 */
- NOSYS /* 70 */
- NOSYS /* 71 */
- NOSYS /* 72 */
- NOSYS /* 73 */
- NOSYS /* 74 */
- NOSYS /* 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(sn1_uname, 1) /* 135 */
- NOSYS /* 136 */
- NOSYS /* 137 */
- NOSYS /* 138 */
- NOSYS /* 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 */
- NOSYS /* 159 */
- NOSYS /* 160 */
- NOSYS /* 161 */
- NOSYS /* 162 */
- NOSYS /* 163 */
- NOSYS /* 164 */
- NOSYS /* 165 */
- NOSYS /* 166 */
- NOSYS /* 167 */
- NOSYS /* 168 */
- NOSYS /* 169 */
- NOSYS /* 170 */
- NOSYS /* 171 */
- NOSYS /* 172 */
- NOSYS /* 173 */
- NOSYS /* 174 */
- NOSYS /* 175 */
- NOSYS /* 176 */
- NOSYS /* 177 */
- NOSYS /* 178 */
- NOSYS /* 179 */
- NOSYS /* 180 */
- NOSYS /* 181 */
- NOSYS /* 182 */
- NOSYS /* 183 */
- NOSYS /* 184 */
- NOSYS /* 185 */
- NOSYS /* 186 */
- NOSYS /* 187 */
- NOSYS /* 188 */
- NOSYS /* 189 */
- NOSYS /* 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 */
- NOSYS /* 223 */
- NOSYS /* 224 */
- NOSYS /* 225 */
- NOSYS /* 226 */
- NOSYS /* 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 */
-
-#endif /* lint */
diff --git a/usr/src/lib/brand/sn1/zone/platform.xml b/usr/src/lib/brand/sn1/zone/platform.xml
index 7b1d23294a..8065fa5fd3 100644
--- a/usr/src/lib/brand/sn1/zone/platform.xml
+++ b/usr/src/lib/brand/sn1/zone/platform.xml
@@ -23,8 +23,6 @@
Copyright 2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
- ident "%Z%%M% %I% %E% SMI"
-
DO NOT EDIT THIS FILE.
-->
@@ -37,6 +35,11 @@
<global_mount special="/dev" directory="/dev" type="dev"
opt="attrdir=%R/dev"/>
+ <global_mount special="/usr" directory="/.SUNWnative/usr"
+ opt="ro,nodevices" type="lofs" />
+ <global_mount special="/lib" directory="/.SUNWnative/lib"
+ 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" />
diff --git a/usr/src/lib/brand/sn1/zone/sn1_boot.sh b/usr/src/lib/brand/sn1/zone/sn1_boot.sh
index a1a656c7c7..0ca620a9ed 100644
--- a/usr/src/lib/brand/sn1/zone/sn1_boot.sh
+++ b/usr/src/lib/brand/sn1/zone/sn1_boot.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/ksh -p
#
# CDDL HEADER START
#
@@ -20,11 +20,9 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# sn1 boot script.
#
# The argument to this script is the root of the zone.
@@ -35,20 +33,12 @@ PATH=/sbin:/usr/bin:/usr/sbin; export PATH
ZONEROOT=$1
if [ `uname -p` = "i386" ]; then
- ARCH64=amd64
+ ARCH64=amd64
elif [ `uname -p` = "sparc" ]; then
- ARCH64=sparcv9
+ ARCH64=sparcv9
else
- echo "Unsupported architecture: " `uname -p`
- exit 2
-fi
-
-crle -u -c ${ZONEROOT}/root/var/ld/ld.config \
- -e LD_PRELOAD=/usr/lib/sn1_brand.so.1
-
-if [ `isainfo -b` -eq 64 ]; then
- crle -64 -u -c ${ZONEROOT}/root/var/ld/64/ld.config \
- -e LD_PRELOAD=/usr/lib/$ARCH64/sn1_brand.so.1
+ echo "Unsupported architecture: " `uname -p` >&2
+ exit 2
fi
exit 0
diff --git a/usr/src/pkgdefs/SUNWsn1uint/prototype_i386 b/usr/src/pkgdefs/SUNWsn1uint/prototype_i386
index 6e5a79ddea..2b12b3d6ad 100644
--- a/usr/src/pkgdefs/SUNWsn1uint/prototype_i386
+++ b/usr/src/pkgdefs/SUNWsn1uint/prototype_i386
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Fake Solaris N-1 Brand
#
@@ -33,3 +31,7 @@
f none usr/lib/sn1_brand.so.1 0755 root bin
d none usr/lib/amd64 0755 root bin
f none usr/lib/amd64/sn1_brand.so.1 0755 root bin
+d none usr/lib/brand/sn1/amd64 755 root bin
+s none usr/lib/brand/sn1/64=amd64 755 root bin
+f none usr/lib/brand/sn1/amd64/sn1_librtld_db.so.1 755 root bin
+f none usr/lib/brand/sn1/sn1_librtld_db.so.1 755 root bin
diff --git a/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc b/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc
index 64dc2ed860..f3d88ec5eb 100644
--- a/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc
@@ -19,17 +19,19 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Fake Solaris N-1 Brand
#
!include prototype_com
# The user library
+d none usr/lib/brand/sn1/sparcv9 755 root bin
+s none usr/lib/brand/sn1/64=sparcv9 755 root bin
+f none usr/lib/brand/sn1/sn1_librtld_db.so.1 755 root bin
+f none usr/lib/brand/sn1/sparcv9/sn1_librtld_db.so.1 755 root bin
f none usr/lib/sn1_brand.so.1 0755 root bin
d none usr/lib/sparcv9 0755 root bin
f none usr/lib/sparcv9/sn1_brand.so.1 0755 root bin
diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c
index 5500ae6713..12ce4d47d5 100644
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c
+++ b/usr/src/uts/common/brand/lx/os/lx_brand.c
@@ -155,7 +155,6 @@ lx_proc_exit(proc_t *p, klwp_t *lwp)
lx_exitlwp(lwp);
kmem_free(p->p_brand_data, sizeof (struct lx_proc_data));
p->p_brand_data = NULL;
- p->p_brand = &native_brand;
}
}
diff --git a/usr/src/uts/common/brand/sn1/sn1_brand.c b/usr/src/uts/common/brand/sn1/sn1_brand.c
index 7d980026ae..8ed74ae469 100644
--- a/usr/src/uts/common/brand/sn1/sn1_brand.c
+++ b/usr/src/uts/common/brand/sn1/sn1_brand.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/errno.h>
#include <sys/exec.h>
#include <sys/kmem.h>
@@ -36,6 +34,7 @@
#include <sys/thread.h>
#include <sys/cmn_err.h>
#include <sys/archsystm.h>
+#include <sys/pathname.h>
#include <sys/machbrand.h>
#include <sys/brand.h>
@@ -83,7 +82,7 @@ struct brand_ops sn1_brops = {
struct brand_mach_ops sn1_mops = {
sn1_brand_syscall_callback,
- sn1_brand_syscall_callback
+ sn1_brand_syscall32_callback
};
#else /* sparc */
@@ -135,13 +134,14 @@ sn1_setbrand(proc_t *p)
{
ASSERT(p->p_brand == &sn1_brand);
ASSERT(p->p_brand_data == NULL);
- 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 (sn1_proc_data_t), KM_SLEEP);
(void) sn1_initlwp(p->p_tlist->t_lwp);
}
@@ -168,7 +168,11 @@ int
sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
{
- proc_t *p = curproc;
+ sn1_proc_data_t *spd;
+ sn1_brand_reg_t reg;
+ proc_t *p = curproc;
+ int err;
+
*rval = 0;
/*
@@ -186,10 +190,56 @@ sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
return (ENOSYS);
ASSERT(p->p_brand == &sn1_brand);
-
- if (cmd == B_REGISTER) {
- ASSERT(p->p_brand_data == NULL);
- p->p_brand_data = (void *)arg1;
+ ASSERT(p->p_brand_data != NULL);
+
+ spd = (sn1_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 {
+ sn1_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 != SN1_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 (sn1_elf_data_t)) != 0)
+ return (EFAULT);
+#if defined(_LP64)
+ } else {
+ sn1_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);
}
@@ -197,17 +247,22 @@ sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
}
/*
- * Copy the per-process brand data from a parent proc to a child. In the
- * sn1 brand, the only per-process state is the address of the user-space
- * handler.
+ * Copy the per-process brand data from a parent proc to a child.
*/
void
sn1_copy_procdata(proc_t *child, proc_t *parent)
{
+ sn1_proc_data_t *spd;
+
ASSERT(parent->p_brand == &sn1_brand);
ASSERT(child->p_brand == &sn1_brand);
+ ASSERT(parent->p_brand_data != NULL);
+ ASSERT(child->p_brand_data == NULL);
- child->p_brand_data = NULL;
+ /* Just duplicate all the proc data of the parent for the child */
+ spd = kmem_alloc(sizeof (sn1_proc_data_t), KM_SLEEP);
+ bcopy(parent->p_brand_data, spd, sizeof (sn1_proc_data_t));
+ child->p_brand_data = spd;
}
/*ARGSUSED*/
@@ -215,6 +270,7 @@ void
sn1_proc_exit(struct proc *p, klwp_t *l)
{
ASSERT(p->p_brand == &sn1_brand);
+ ASSERT(p->p_brand_data != NULL);
/*
* We should only be called from proc_exit(), when we know that
@@ -222,14 +278,21 @@ sn1_proc_exit(struct proc *p, klwp_t *l)
*/
ASSERT(p->p_tlist == p->p_tlist->t_forw);
+ /* upon exit, free our lwp brand data */
+ (void) sn1_freelwp(ttolwp(curthread));
+
+ /* upon exit, free our proc brand data */
+ kmem_free(p->p_brand_data, sizeof (sn1_proc_data_t));
p->p_brand_data = NULL;
- l->lwp_brand = NULL;
}
void
sn1_exec()
{
+ sn1_proc_data_t *spd = curproc->p_brand_data;
+
ASSERT(curproc->p_brand == &sn1_brand);
+ ASSERT(curproc->p_brand_data != NULL);
ASSERT(ttolwp(curthread)->lwp_brand != NULL);
/*
@@ -238,8 +301,15 @@ sn1_exec()
*/
ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
- /* upon exec, reset our user-land handler callback entry point */
- curproc->p_brand_data = NULL;
+ /* Upon exec, reset our lwp brand data. */
+ (void) sn1_freelwp(ttolwp(curthread));
+ (void) sn1_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*/
@@ -247,6 +317,7 @@ int
sn1_initlwp(klwp_t *l)
{
ASSERT(l->lwp_procp->p_brand == &sn1_brand);
+ ASSERT(l->lwp_procp->p_brand_data != NULL);
ASSERT(l->lwp_brand == NULL);
l->lwp_brand = (void *)-1;
return (0);
@@ -259,6 +330,9 @@ sn1_forklwp(klwp_t *p, klwp_t *c)
ASSERT(p->lwp_procp->p_brand == &sn1_brand);
ASSERT(c->lwp_procp->p_brand == &sn1_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 sn1_initlwp() */
ASSERT(p->lwp_brand != NULL);
ASSERT(c->lwp_brand != NULL);
@@ -268,8 +342,8 @@ sn1_forklwp(klwp_t *p, klwp_t *c)
void
sn1_freelwp(klwp_t *l)
{
- /* This lwp died during birth */
ASSERT(l->lwp_procp->p_brand == &sn1_brand);
+ ASSERT(l->lwp_procp->p_brand_data != NULL);
ASSERT(l->lwp_brand != NULL);
l->lwp_brand = NULL;
}
@@ -281,6 +355,7 @@ sn1_lwpexit(klwp_t *l)
proc_t *p = l->lwp_procp;
ASSERT(l->lwp_procp->p_brand == &sn1_brand);
+ ASSERT(l->lwp_procp->p_brand_data != NULL);
ASSERT(l->lwp_brand != NULL);
/*
@@ -295,24 +370,393 @@ sn1_lwpexit(klwp_t *l)
/*ARGSUSED*/
void
-sn1_init_brand_data(zone_t *zone)
+sn1_free_brand_data(zone_t *zone)
{
}
/*ARGSUSED*/
void
-sn1_free_brand_data(zone_t *zone)
+sn1_init_brand_data(zone_t *zone)
+{
+}
+
+#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
sn1_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)
{
- args->brandname = "sn1";
- return ((args->execswp->exec_func)(vp, uap, args, idatap, level + 1,
- execsz, setid, exec_file, cred, 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);
+ sn1_proc_data_t *spd;
+ sn1_elf_data_t sed, *sedp;
+ char *linker;
+ uintptr_t lddata; /* lddata of executable's linker */
+
+ ASSERT(curproc->p_brand == &sn1_brand);
+ ASSERT(curproc->p_brand_data != NULL);
+
+ spd = (sn1_proc_data_t *)curproc->p_brand_data;
+ sedp = &spd->spd_elf_data;
+
+ args->brandname = SN1_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 = SN1_LIB;
+ linker = SN1_LINKER;
+#if defined(_LP64)
+ } else {
+ args->emulator = SN1_LIB32;
+ linker = SN1_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.", SN1_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_lddata = NULL;
+ sedp->sed_base = NULL;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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 sn1_auxv[] = {
+ { AT_SUN_BRAND_AUX1, 0 },
+ { AT_SUN_BRAND_AUX2, 0 },
+ { AT_SUN_BRAND_AUX3, 0 }
+ };
+
+ ASSERT(sn1_auxv[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
+ sn1_auxv[0].a_un.a_val = sed.sed_lddata;
+
+ if (copyout(&sn1_auxv, args->auxp_brand,
+ sizeof (sn1_auxv)) != 0)
+ return (EFAULT);
+#if defined(_LP64)
+ } else {
+ auxv32_t sn1_auxv32[] = {
+ { AT_SUN_BRAND_AUX1, 0 },
+ { AT_SUN_BRAND_AUX2, 0 },
+ { AT_SUN_BRAND_AUX3, 0 }
+ };
+
+ ASSERT(sn1_auxv32[0].a_type == AT_SUN_BRAND_SN1_LDDATA);
+ sn1_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
+ if (copyout(&sn1_auxv32, args->auxp_brand,
+ sizeof (sn1_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++) {
+ 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;
+ 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;
+ }
+ break;
+ case AT_ENTRY:
+ up->u_auxv[i].a_un.a_val = sedp->sed_entry;
+ break;
+ case AT_PHDR:
+ up->u_auxv[i].a_un.a_val = sedp->sed_phdr;
+ break;
+ case AT_PHENT:
+ up->u_auxv[i].a_un.a_val = sedp->sed_phent;
+ break;
+ case AT_PHNUM:
+ up->u_auxv[i].a_un.a_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;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * 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);
}
@@ -328,7 +772,18 @@ _init(void)
* library.
*/
sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
- sn1_emulation_table[SYS_uname] = 1;
+ sn1_emulation_table[SYS_read] = 1; /* 3 */
+ sn1_emulation_table[SYS_write] = 1; /* 4 */
+ sn1_emulation_table[SYS_wait] = 1; /* 7 */
+ sn1_emulation_table[SYS_time] = 1; /* 13 */
+ sn1_emulation_table[SYS_getpid] = 1; /* 20 */
+ sn1_emulation_table[SYS_mount] = 1; /* 21 */
+ sn1_emulation_table[SYS_getuid] = 1; /* 24 */
+ sn1_emulation_table[SYS_times] = 1; /* 43 */
+ sn1_emulation_table[SYS_getgid] = 1; /* 47 */
+ sn1_emulation_table[SYS_utssys] = 1; /* 57 */
+ sn1_emulation_table[SYS_readlink] = 1; /* 90 */
+ sn1_emulation_table[SYS_uname] = 1; /* 135 */
err = mod_install(&modlinkage);
if (err) {
diff --git a/usr/src/uts/common/brand/sn1/sn1_brand.h b/usr/src/uts/common/brand/sn1/sn1_brand.h
index a4efca189b..01c3b6f401 100644
--- a/usr/src/uts/common/brand/sn1/sn1_brand.h
+++ b/usr/src/uts/common/brand/sn1/sn1_brand.h
@@ -19,27 +19,106 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SN1_BRAND_H
#define _SN1_BRAND_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
+#include <sys/types.h>
+
+#define SN1_BRANDNAME "sn1"
+
+#define SN1_VERSION_1 1
+#define SN1_VERSION SN1_VERSION_1
+
+#define SN1_NATIVE_DIR "/.SUNWnative/"
+#define SN1_LIB_NAME "sn1_brand.so.1"
+#define SN1_LINKER_NAME "ld.so.1"
+
+#define SN1_LIB32 SN1_NATIVE_DIR "usr/lib/" SN1_LIB_NAME
+#define SN1_LINKER32 "/lib/" SN1_LINKER_NAME
+
+#define SN1_LIB64 SN1_NATIVE_DIR "usr/lib/64/" SN1_LIB_NAME
+#define SN1_LINKER64 "/lib/64/" SN1_LINKER_NAME
+
+#if defined(_LP64)
+#define SN1_LIB SN1_LIB64
+#define SN1_LINKER SN1_LINKER64
+#else /* !_LP64 */
+#define SN1_LIB SN1_LIB32
+#define SN1_LINKER SN1_LINKER32
+#endif /* !_LP64 */
+
+/*
+ * Aux vector containing lddata pointer of brand library linkmap.
+ * Used by lx_librtld_db.
+ */
+#define AT_SUN_BRAND_SN1_LDDATA AT_SUN_BRAND_AUX1
+
+/*
+ * Information needed by the sn1 library to launch an executable.
+ */
+typedef struct sn1_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;
+} sn1_elf_data_t;
+
+/*
+ * Structure used to register a branded processes
+ */
+typedef struct sn1_brand_reg {
+ uint_t sbr_version; /* version number */
+ caddr_t sbr_handler; /* base address of handler */
+} sn1_brand_reg_t;
+
+#if defined(_KERNEL)
+#if defined(_SYSCALL32)
+typedef struct sn1_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;
+} sn1_elf_data32_t;
+
+typedef struct sn1_brand_reg32 {
+ uint32_t sbr_version; /* version number */
+ caddr32_t sbr_handler; /* base address of handler */
+} sn1_brand_reg32_t;
+#endif /* _SYSCALL32 */
+
+/*
+ * Information associated with all sn1 branded processes
+ */
+typedef struct sn1_proc_data {
+ caddr_t spd_handler; /* address of user-space handler */
+ sn1_elf_data_t spd_elf_data; /* ELF data for sn1 application */
+} sn1_proc_data_t;
+
void sn1_brand_syscall_callback(void);
-void sn1_brand_sysenter_callback(void);
-void sn1_brand_int91_callback(void);
-#ifdef __amd64
void sn1_brand_syscall32_callback(void);
-#endif
-extern struct brand *sbrand;
+#if !defined(sparc)
+void sn1_brand_sysenter_callback(void);
+#endif /* !sparc */
+
+#if defined(__amd64)
+void sn1_brand_int91_callback(void);
+#endif /* __amd64 */
+#endif /* _KERNEL */
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/brand/sn1/sn1_offsets.in b/usr/src/uts/common/brand/sn1/sn1_offsets.in
new file mode 100644
index 0000000000..0e531f26fd
--- /dev/null
+++ b/usr/src/uts/common/brand/sn1/sn1_offsets.in
@@ -0,0 +1,30 @@
+\
+\ Copyright 2008 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
+\
+\ Sn1 brand structure offset for use in assembly code.
+\
+
+#include <sn1_brand.h>
+
+sn1_proc_data_t
+ spd_handler
diff --git a/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s b/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s
index 6d0a3fc60a..55edd9b621 100644
--- a/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s
+++ b/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#if defined(lint)
#include <sys/systm.h>
@@ -34,6 +32,7 @@
#include <sys/asm_linkage.h>
#include <sys/privregs.h>
#include <sys/segments.h>
+#include <sn1_offsets.h>
#include "assym.h"
#endif /* lint */
@@ -149,12 +148,14 @@ sn1_brand_int91_callback(void)
/*
* See if this process has a user-space hdlr registered for it. For the
* sn1 brand, the per-process brand data holds the address of the handler.
- * As shown in the stack diagrams above, the callback code leaves that data
- * at these offsets.
+ * As shown in the stack diagrams below, the callback code leaves that data
+ * at these offsets. So check if sn1_proc_data_t->spd_handler is non-NULL.
*/
-#define CHECK_FOR_HANDLER(scr) \
- GET_PROCP(SP_REG, 1, scr) /* get proc pointer */ ;\
- cmp $0, P_BRAND_DATA(scr) /* check p_brand_data */ ;\
+#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
/*
@@ -213,11 +214,12 @@ ENTRY(sn1_brand_syscall32_callback)
movl %ecx, (%rsp) /* Save post-syscall addr on stack */
/*
- * To 'return' to our user-space hdlr, we just need to copy
- * its address into %ecx. user-space hdlr == p_brand_data for sn1
+ * To 'return' to our user-space handler, we just need to copy
+ * its address into %rcx.
*/
- GET_P_BRAND_DATA(%r15, 1, %rcx);
- movq (%r15), %r15 /* Restore scratch register */
+ 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_sysretl
9:
popq %r15
@@ -239,11 +241,12 @@ ENTRY(sn1_brand_syscall_callback)
movq %rcx, (%rsp) /* Save post-syscall addr on stack */
/*
- * To 'return' to our user-space hdlr, we just need to copy
- * its address into %ecx. user-space hdlr == p_brand_data for sn1
+ * To 'return' to our user-space handler, we just need to copy
+ * its address into %rcx.
*/
- GET_P_BRAND_DATA(%r15, 1, %rcx);
- movq (%r15), %r15 /* Restore scratch register */
+ 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_sysretq
9:
popq %r15
@@ -264,7 +267,8 @@ ENTRY(sn1_brand_sysenter_callback)
subq $4, %rcx /* Save room for user ret addr */
movq %rdx, (%rcx) /* Save current return addr */
- GET_P_BRAND_DATA(%rsp, 1, %rdx) /* get p_brand_data */
+ 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 */
sysexit
9:
@@ -288,8 +292,9 @@ ENTRY(sn1_brand_int91_callback)
CALLBACK_PROLOGUE(%rax, %r15, %r15b)
pushq %rax /* Save scratch register */
- GET_P_BRAND_DATA(%rsp, 2, %r15) /* get p_brand_data */
- GET_V(%rsp, 2, V_SSP, %rax) /* Get saved %esp */
+ GET_P_BRAND_DATA(%rsp, 2, %r15) /* get p_brand_data */
+ movq SPD_HANDLER(%r15), %r15 /* get sn1_proc_data->spd_handler ptr */
+ GET_V(%rsp, 2, V_SSP, %rax) /* Get saved %esp */
movq %r15, (%rax) /* replace iret target address with hdlr */
/*
@@ -341,8 +346,9 @@ ENTRY(sn1_brand_syscall_callback)
pushl %eax /* Save scratch register */
/* replace iret target address with user-space hdlr */
- GET_P_BRAND_DATA(%esp, 2, %ebx)
- SET_V(%esp, 2, V_U_EIP, %ebx)
+ 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
@@ -375,7 +381,8 @@ ENTRY(sn1_brand_sysenter_callback)
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 */
+ GET_P_BRAND_DATA(%esp, 1, %edx) /* get p_brand_data */
+ movl SPD_HANDLER(%edx), %edx /* get p_brand_data->spd_handler */
popl %ebx /* Restore scratch register */
sysexit
9:
diff --git a/usr/src/uts/intel/sn1_brand/Makefile b/usr/src/uts/intel/sn1_brand/Makefile
index 93306ea413..522ce45104 100644
--- a/usr/src/uts/intel/sn1_brand/Makefile
+++ b/usr/src/uts/intel/sn1_brand/Makefile
@@ -22,8 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# This makefile drives the production of the kernel component of
# the N-1 Solaris brand
#
@@ -31,15 +29,18 @@
#
# Path to the base of the uts directory tree (usually /usr/src/uts).
#
-UTSBASE = ../..
+UTSBASE = ../..
+SN1_BASE = $(UTSBASE)/common/brand/sn1
#
# Define the module and object file sets.
#
-MODULE = sn1_brand
-OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_BRAND_DIR)/$(MODULE)
+MODULE = sn1_brand
+OFFSETS_H = $(OBJS_DIR)/sn1_offsets.h
+OFFSETS_SRC = $(SN1_BASE)/sn1_offsets.in
+OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE = $(ROOT_BRAND_DIR)/$(MODULE)
#
# Include common rules.
@@ -49,12 +50,17 @@ include $(UTSBASE)/intel/Makefile.intel
#
# Define targets
#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
+ALL_TARGET = $(OFFSETS_H) $(BINARY)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+
-INC_PATH += -I$(UTSBASE)/common/brand/sn1
+#
+# Update compiler variables.
+#
+INC_PATH += -I$(SN1_BASE) -I$(OBJS_DIR)
AS_INC_PATH += -I$(UTSBASE)/i86pc/genassym/$(OBJS_DIR)
+LDFLAGS += -dy -Nexec/elfexec
#
# Ugh, this is a gross hack. Sn1_brand_asm.s uses lots of defines
@@ -89,6 +95,12 @@ 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
diff --git a/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s b/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s
index 2a8c8b92e0..f1052a3332 100644
--- a/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s
+++ b/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s
@@ -19,40 +19,42 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#if defined(lint)
#include <sys/systm.h>
-#else /* lint */
-
-#include <sys/asm_linkage.h>
-#include <sys/machthread.h>
-#include <sys/privregs.h>
-#include "assym.h"
-
-#endif /* lint */
-
-#ifdef lint
+void
+sn1_brand_syscall32_callback(void)
+{
+}
void
sn1_brand_syscall_callback(void)
{
}
-#else /* lint */
+#else /* !lint */
-#ifdef sun4v
+#include <sys/asm_linkage.h>
+#include <sys/machthread.h>
+#include <sys/privregs.h>
+#include <sn1_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
@@ -62,6 +64,10 @@ sn1_brand_syscall_callback(void)
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
@@ -72,16 +78,57 @@ sn1_brand_syscall_callback(void)
* %g1: return point
* %g2: pointer to our cpu structure
*/
+ ENTRY(sn1_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(sn1_brand_syscall32_callback)
+
+ /*
+ * Input parameters:
+ * %g1: return point
+ * %g2: pointer to our cpu structure
+ */
ENTRY(sn1_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(sn1_brand_syscall_callback)
+ ENTRY(sn1_brand_syscall_callback_common)
+_entry:
/*
- * save some locals in the CPU tmp area to give us a little
+ * 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]
-#ifdef sun4v
+#if defined(sun4v)
/*
* On sun4v save our input parameters (which are stored in the
* alternate globals) since we'll need to switch between alternate
@@ -90,87 +137,145 @@ sn1_brand_syscall_callback(void)
*/
stn %l2, [%g2 + CPU_TMP3]
stn %l3, [%g2 + CPU_TMP4]
- mov %g1, %l2
- mov %g2, %l3
+
+ 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, then switch back to the alternate globals.
- *
- * If the system call number is >= 1024, then it is coming from the
- * emulation support library and should not be emulated.
+ * number.
*/
GLOBALS_SWAP(%l0) ! switch to normal globals
- cmp %g1, 1024 ! is this call from the library?
- bl,a 1f
+
+ /*
+ * 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 2f ! jump back into syscall path
-1:
+ 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.
+ * nothing happened. %l1 contains the syscall we're invoking.
*/
set sn1_emulation_table, %g3
ldn [%g3], %g3
add %g3, %l1, %g3
ldub [%g3], %g3
- brz %g3, 2f
+ brz %g3, _exit
nop
/*
* Find the address of the userspace handler.
- * cpu->cpu_thread->t_procp->p_brandhdlr.
+ * cpu->cpu_thread->t_procp->p_brand_data->spd_handler.
*/
-#ifdef sun4v
+#if defined(sun4v)
! restore the alternate global registers after incrementing %gl
mov %l3, %g2
#endif /* sun4v */
- ldn [%g2 + CPU_THREAD], %g3 ! load thread pointer
- ldn [%g3 + T_PROCP], %g3 ! get proc pointer
- ldn [%g3 + P_BRAND_DATA], %g3 ! get brand handler
- brz %g3, 2f ! has it been set?
+ 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 %g6,
+ * 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, %g3, %tnpc ! setup tnpc
+ wrpr %g0, %g5, %tnpc ! setup tnpc
GLOBALS_SWAP(%l0) ! switch to normal globals
- mov %l1, %g6 ! pass tnpc to user code in %g6
+ 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 */
-#ifdef sun4v
+#if defined(sun4v)
set fast_trap_done_chk_intr, %l2
#else /* !sun4v */
set fast_trap_done_chk_intr, %g1
#endif /* !sun4v */
-2:
+_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.
*/
-#ifdef sun4v
+#if defined(sun4v)
! restore the alternate global registers after incrementing %gl
- mov %l3, %g2
- mov %l2, %g1
+ 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
@@ -181,5 +286,5 @@ sn1_brand_syscall_callback(void)
jmp %g1
nop
- SET_SIZE(sn1_brand_syscall_callback)
-#endif /* lint */
+ SET_SIZE(sn1_brand_syscall_callback_common)
+#endif /* !lint */
diff --git a/usr/src/uts/sun4u/sn1_brand/Makefile b/usr/src/uts/sun4u/sn1_brand/Makefile
index 3531a5eacf..ad7b808e02 100644
--- a/usr/src/uts/sun4u/sn1_brand/Makefile
+++ b/usr/src/uts/sun4u/sn1_brand/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# This makefile drives the production of the kernel component of
# the N-1 Solaris brand
#
@@ -31,15 +29,18 @@
#
# Path to the base of the uts directory tree (usually /usr/src/uts).
#
-UTSBASE = ../..
+UTSBASE = ../..
+SN1_BASE = $(UTSBASE)/common/brand/sn1
#
# Define the module and object file sets.
#
-MODULE = sn1_brand
-OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE)
+MODULE = sn1_brand
+OFFSETS_H = $(OBJS_DIR)/sn1_offsets.h
+OFFSETS_SRC = $(SN1_BASE)/sn1_offsets.in
+OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE)
#
# Include common rules.
@@ -49,12 +50,15 @@ include $(UTSBASE)/sun4u/Makefile.sun4u
#
# Define targets
#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-INC_PATH += -I$(UTSBASE)/common/brand/sn1
+ALL_TARGET = $(OFFSETS_H) $(BINARY)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+#
+# Update compiler variables.
+#
+INC_PATH += -I$(SN1_BASE) -I$(OBJS_DIR)
+LDFLAGS += -dy -Nexec/elfexec
#
# Default build targets.
@@ -78,6 +82,12 @@ 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
diff --git a/usr/src/uts/sun4v/sn1_brand/Makefile b/usr/src/uts/sun4v/sn1_brand/Makefile
index 0333e5fe15..6a9dc5e1af 100644
--- a/usr/src/uts/sun4v/sn1_brand/Makefile
+++ b/usr/src/uts/sun4v/sn1_brand/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# This makefile drives the production of the kernel component of
# the N-1 Solaris brand
#
@@ -31,15 +29,18 @@
#
# Path to the base of the uts directory tree (usually /usr/src/uts).
#
-UTSBASE = ../..
+UTSBASE = ../..
+SN1_BASE = $(UTSBASE)/common/brand/sn1
#
# Define the module and object file sets.
#
-MODULE = sn1_brand
-OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE)
+MODULE = sn1_brand
+OFFSETS_H = $(OBJS_DIR)/sn1_offsets.h
+OFFSETS_SRC = $(SN1_BASE)/sn1_offsets.in
+OBJECTS = $(SN1_BRAND_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(SN1_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE)
#
# Include common rules.
@@ -49,12 +50,15 @@ include $(UTSBASE)/sun4v/Makefile.sun4v
#
# Define targets
#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-INC_PATH += -I$(UTSBASE)/common/brand/sn1
+ALL_TARGET = $(OFFSETS_H) $(BINARY)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE)
+#
+# Update compiler variables.
+#
+INC_PATH += -I$(SN1_BASE) -I$(OBJS_DIR)
+LDFLAGS += -dy -Nexec/elfexec
#
# Default build targets.
@@ -78,6 +82,12 @@ 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