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; \ 349: call 8f; \ 35 sethi %hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 368: 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; \ 44x: 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 65ENTRY_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 721: 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 1091: ! 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 130FUNC(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 1421: 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 1512: 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 160FUNC(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 1681: 169 mov %o0, %i0 170 restore 171 jmp %g6 172 nop 173 SET_SIZE(trap0rtn) 174 175! 176! nullsys 177! 178FUNC(nullsys) 179 clr %o0 180 b,a trap0rtn 181 SET_SIZE(nullsys) 182 183! 184! nosys 185! 186FUNC(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