1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 .file "sbcp.s" 27 28 #include <sys/asm_linkage.h> 29 #include <sys/link.h> 30 #include <sys/syscall.h> 31 32 #define PIC_SETUP(r) \ 33 mov %o7, %g1; \ 34 9: call 8f; \ 35 sethi %hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 36 8: or %r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 37 add %r, %o7, %r; \ 38 mov %g1, %o7 39 40 #define FUNC(x) \ 41 .section ".text"; \ 42 .align 4; \ 43 .type x, #function; \ 44 x: 45 46 #define ENOSYS 90 /* 4.x ENOSYS */ 47 48 /* derived from <sys/exechdr.h>, which we can't include */ 49 #define A_MAGIC 0x02 /* offset of a_magic field */ 50 #define A_ENTRY 0x14 /* offset of a_entry field */ 51 #define ZMAGIC 0413 /* magic number for demand paged executable */ 52 53 .global atexit, errno 54 55 ! 56 ! _start - execution starts here (after the runtime linker runs) 57 ! 58 ! The SPARC ABI defines our "environment" at this point, see page 3-34. 59 ! Register the exit handler, register the trap0 handler, find the 60 ! entry point, and jump to it. We depend on the stack (argv, envp) 61 ! being compatible between 4.x and 5.x. We also depend on the 62 ! runtime linker to set up ``environ''. 63 ! 64 65 ENTRY_NP(_start) 66 tst %g1 ! is there a handler to register? 67 bz 1f ! no 68 nop 69 mov %g1, %o0 70 call atexit ! yes, register it with atexit() 71 nop 72 1: 73 74 ! 75 ! Aside from a value in %g1, there were no arguments explicitly 76 ! passed to this routine, but we do know how our initial stack has 77 ! been setup by the kernel. The stack format is documented in: 78 ! usr/src/cmd/sgs/rtld/sparc/boot.s 79 ! usr/src/cmd/sgs/rtld/sparcv9/boot.s 80 ! 81 ! Since we want to invoke the following c initalization routine: 82 ! sbcp_init(int argc, char *argv[], char *envp[])) 83 ! we need to troll through the stack to setup it's argument values. 84 ! 85 save %sp, -SA(MINFRAME + EB_MAX_SIZE32), %sp 86 87 ldn [%fp + WINDOWSIZE + STACK_BIAS], %o0 ! get argc 88 add %fp, + WINDOWSIZE + CPTRSIZE + STACK_BIAS, %o1 ! get argv 89 90 add %o0, 1, %l0 ! add 1 to argc for last element of 0 91 sll %l0, CPTRSHIFT, %l0 ! multiply argc by pointer size 92 add %o1, %l0, %o2 ! and add to argv to get envp 93 94 call sbcp_init ! Call our c initalization routine 95 nop 96 restore 97 98 PIC_SETUP(g2) 99 ld [%g2+trap0], %g1 100 ta 9 101 102 ! jump to the main program's entry point 103 104 sethi %hi(0x2000), %o0 105 lduh [%o0 + A_MAGIC], %g1 106 cmp %g1, ZMAGIC ! is it a ZMAGIC executable? 107 be,a 1f ! yes, 108 ld [%o0 + A_ENTRY], %o0 ! get entry point 109 1: ! else, assume entry point is 0x2000 110 jmp %o0 111 nop 112 SET_SIZE(_start) 113 114 ! 115 ! trap0 - glue between 4.x syscall trap and 5.x BCP routine 116 ! 117 ! enter with: 118 ! %g1 syscall number 119 ! %g6 return address (after trap instruction) 120 ! 121 ! We used to use %g7, but that conflicts with threading code 122 ! which uses %g7 as the curthread pointer. That is why we 123 ! changed to using %g6 instead. 124 ! 125 ! We use an extra window to save the %o registers we're entered 126 ! with (which the 4.x system call stubs depend on) and to allow 127 ! recursive traps (e.g., from a signal handler). 128 ! 129 130 FUNC(trap0) 131 save %sp, -SA(MINFRAME), %sp 132 tst %g1 133 be 1f 134 nop 135 mov %i0, %o0 136 mov %i1, %o1 137 mov %i2, %o2 138 mov %i3, %o3 139 mov %i4, %o4 140 mov %i5, %o5 141 ba,a 2f 142 1: 143 ! indir syscall 144 mov %i0, %g1 145 mov %i1, %o0 146 mov %i2, %o1 147 mov %i3, %o2 148 mov %i4, %o3 149 mov %i5, %o4 150 ld [%fp + MINFRAME], %o5 151 2: 152 sll %g1, 4, %l1 153 PIC_SETUP(l0) 154 ld [%l0+sysent], %l0 155 add %l1, %l0, %l1 156 jmp %l1 ! jump into branch table 157 nop 158 SET_SIZE(trap0) 159 160 FUNC(trap0rtn) 161 cmp %o0, -1 162 bne 1f 163 addcc %g0, %g0, %g0 ! psr &= ~C 164 PIC_SETUP(o1) 165 ld [%o1+errno], %o1 166 ld [%o1], %o0 167 subcc %g0, 1, %g0 ! psr |= C 168 1: 169 mov %o0, %i0 170 restore 171 jmp %g6 172 nop 173 SET_SIZE(trap0rtn) 174 175 ! 176 ! nullsys 177 ! 178 FUNC(nullsys) 179 clr %o0 180 b,a trap0rtn 181 SET_SIZE(nullsys) 182 183 ! 184 ! nosys 185 ! 186 FUNC(nosys) 187 set ENOSYS, %o1 188 PIC_SETUP(g2) 189 ld [%g2+errno], %g2 190 st %o1, [%g2] 191 set -1, %o0 192 b,a trap0rtn 193 SET_SIZE(nosys) 194 195 ! 196 ! Have to #include the sysent table and stubs so that all 197 ! symbols referenced between here and there are "static" 198 ! to this module so the assembler can resolve them without 199 ! the linker needing to deal with them at run time. 200 ! 201 #include "sysent.s" 202