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