Mercurial > illumos > illumos-gate
changeset 7933:6a8cc62fe2a1
6409860 sn1 brand should use elfexec()
6540437 sn1 brand doesn't support indirect system calls
line wrap: on
line diff
--- a/usr/src/Targetdirs Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/Targetdirs Fri Oct 24 00:15:39 2008 -0700 @@ -354,7 +354,8 @@ /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 @@ /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)/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)
--- a/usr/src/lib/brand/sn1/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/lib/brand/sn1/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -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 -SUBDIRS= $(MACH) $(VARIANT_SUBDIRS) zone -$(BUILD64)SUBDIRS += $(MACH64) +include Makefile.sn1 + +# 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)
--- a/usr/src/lib/brand/sn1/Makefile.com Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/Makefile.sn1 Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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 +
--- a/usr/src/lib/brand/sn1/amd64/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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" -# -# lib/brand/sn1/amd64/Makefile - -ISASRCDIR=. - -include ../Makefile.com -include ../../../Makefile.lib.64 - -CPPFLAGS += -D_SYSCALL32 - -install: all $(ROOTLIBS64)
--- a/usr/src/lib/brand/sn1/amd64/sn1_handler.s Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 */
--- a/usr/src/lib/brand/sn1/common/mapfile-vers Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +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" - -# -# Scope everything local -- our .init section is our only public interface. -# -{ - local: - *; -};
--- a/usr/src/lib/brand/sn1/common/sn1_brand.c Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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); -}
--- a/usr/src/lib/brand/sn1/common/sn1_brand.h Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 */
--- a/usr/src/lib/brand/sn1/i386/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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" -# -# lib/brand/sn1/i386/Makefile - -ISASRCDIR=. - -ASFLAGS += $(AS_PICFLAGS) -P -D_ASM - -include ../Makefile.com - -install: all $(ROOTLIBS)
--- a/usr/src/lib/brand/sn1/i386/sn1_handler.s Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/Makefile.com Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,80 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/amd64/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +COBJS64 = sn1_librtld_db64.o + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB) +DYNFLAGS += -M../common/mapfile-vers.64 + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/amd64/mapfile-vers Fri Oct 24 00:15:39 2008 -0700 @@ -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; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/common/mapfile-vers.64 Fri Oct 24 00:15:39 2008 -0700 @@ -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; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/common/sn1_librtld_db.c Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,299 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/i386/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/sparc/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/sparcv9/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +COBJS64 = sn1_librtld_db64.o + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB) +DYNFLAGS += -M../common/mapfile-vers.64 + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/librtld_db/sparcv9/mapfile-vers Fri Oct 24 00:15:39 2008 -0700 @@ -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; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile.com Fri Oct 24 00:15:39 2008 -0700 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,41 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_crt.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_handler.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,182 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/amd64/sn1_runexe.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,80 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/common/mapfile-vers Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Scope everything local -- our .init section is our only public interface. +# +{ + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/common/offsets.in Fri Oct 24 00:15:39 2008 -0700 @@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/common/sn1_brand.c Fri Oct 24 00:15:39 2008 -0700 @@ -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, ®)) != 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 */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/i386/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,39 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_crt.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,77 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_handler.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,159 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/i386/sn1_runexe.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,80 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,40 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_crt.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,80 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_handler.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,225 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sparc/sn1_runexe.s Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,82 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sparcv9/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -0,0 +1,41 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/sn1/sn1_brand/sys/sn1_misc.h Fri Oct 24 00:15:39 2008 -0700 @@ -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 */
--- a/usr/src/lib/brand/sn1/sparc/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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" -# -# lib/brand/sn1/sparc/Makefile - -ISASRCDIR=. - -include ../Makefile.com - -ASFLAGS += -xarch=v8plus ${AS_PICFLAGS} - -install: all $(ROOTLIBS)
--- a/usr/src/lib/brand/sn1/sparc/sn1_handler.s Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 */
--- a/usr/src/lib/brand/sn1/sparcv9/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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" -# -# lib/brand/sn1/sparcv9/Makefile - -ISASRCDIR=../sparc - -ASFLAGS_$(CURTYPE) += ${AS_PICFLAGS} - -include ../Makefile.com -include ../../../Makefile.lib.64 - -install: all $(ROOTLIBS64)
--- a/usr/src/lib/brand/sn1/zone/platform.xml Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/lib/brand/sn1/zone/platform.xml Fri Oct 24 00:15:39 2008 -0700 @@ -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" />
--- a/usr/src/lib/brand/sn1/zone/sn1_boot.sh Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/lib/brand/sn1/zone/sn1_boot.sh Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ 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
--- a/usr/src/pkgdefs/SUNWsn1uint/prototype_i386 Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/pkgdefs/SUNWsn1uint/prototype_i386 Fri Oct 24 00:15:39 2008 -0700 @@ -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
--- a/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/pkgdefs/SUNWsn1uint/prototype_sparc Fri Oct 24 00:15:39 2008 -0700 @@ -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
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c Fri Oct 24 00:15:39 2008 -0700 @@ -155,7 +155,6 @@ lx_exitlwp(lwp); kmem_free(p->p_brand_data, sizeof (struct lx_proc_data)); p->p_brand_data = NULL; - p->p_brand = &native_brand; } }
--- a/usr/src/uts/common/brand/sn1/sn1_brand.c Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/common/brand/sn1/sn1_brand.c Fri Oct 24 00:15:39 2008 -0700 @@ -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_mach_ops sn1_mops = { sn1_brand_syscall_callback, - sn1_brand_syscall_callback + sn1_brand_syscall32_callback }; #else /* sparc */ @@ -135,13 +134,14 @@ { 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 @@ 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 @@ return (ENOSYS); ASSERT(p->p_brand == &sn1_brand); + ASSERT(p->p_brand_data != NULL); - if (cmd == B_REGISTER) { - ASSERT(p->p_brand_data == NULL); - p->p_brand_data = (void *)arg1; + 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, ®, sizeof (reg)) != 0) + return (EFAULT); +#if defined(_LP64) + } else { + sn1_brand_reg32_t reg32; + + if (copyin((void *)arg1, ®32, 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 @@ } /* - * 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 @@ 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 @@ */ 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /*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 @@ * 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) {
--- a/usr/src/uts/common/brand/sn1/sn1_brand.h Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/common/brand/sn1/sn1_brand.h Fri Oct 24 00:15:39 2008 -0700 @@ -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_syscall32_callback(void); + +#if !defined(sparc) void sn1_brand_sysenter_callback(void); +#endif /* !sparc */ + +#if defined(__amd64) void sn1_brand_int91_callback(void); -#ifdef __amd64 -void sn1_brand_syscall32_callback(void); -#endif - -extern struct brand *sbrand; +#endif /* __amd64 */ +#endif /* _KERNEL */ #ifdef __cplusplus }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/brand/sn1/sn1_offsets.in Fri Oct 24 00:15:39 2008 -0700 @@ -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
--- a/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/intel/brand/sn1/sn1_brand_asm.s Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ /* * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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:
--- a/usr/src/uts/intel/sn1_brand/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/intel/sn1_brand/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ # # 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 @@ install: $(INSTALL_DEPS) # +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# # Include common targets. # include $(UTSBASE)/intel/Makefile.targ
--- a/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/sun4/brand/sn1/sn1_brand_asm.s Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ 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 @@ * %g1: return point * %g2: pointer to our cpu structure */ - ENTRY(sn1_brand_syscall_callback) + 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) /* - * save some locals in the CPU tmp area to give us a little + * 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: + /* + * 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 @@ */ 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 @@ jmp %g1 nop - SET_SIZE(sn1_brand_syscall_callback) -#endif /* lint */ + SET_SIZE(sn1_brand_syscall_callback_common) +#endif /* !lint */
--- a/usr/src/uts/sun4u/sn1_brand/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/sun4u/sn1_brand/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ # # 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) +LDFLAGS += -dy -Nexec/elfexec # # Default build targets. @@ -78,6 +82,12 @@ install: $(INSTALL_DEPS) # +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# # Include common targets. # include $(UTSBASE)/sun4u/Makefile.targ
--- a/usr/src/uts/sun4v/sn1_brand/Makefile Fri Oct 24 14:11:43 2008 +0800 +++ b/usr/src/uts/sun4v/sn1_brand/Makefile Fri Oct 24 00:15:39 2008 -0700 @@ -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 @@ # # 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) +LDFLAGS += -dy -Nexec/elfexec # # Default build targets. @@ -78,6 +82,12 @@ install: $(INSTALL_DEPS) # +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# # Include common targets. # include $(UTSBASE)/sun4v/Makefile.targ