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/* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30/* 31 * Bootstrap routine for ld.so. Control arrives here either directly from 32 * exec() upon invocation of a dynamically linked program specifying ld.so 33 * as its interpreter. 34 * 35 * On entry, the stack appears as: 36 * 37 * !_______________________! high addresses 38 * ! ! 39 * ! Information ! 40 * ! Block ! 41 * ! (size varies) ! 42 * !_______________________! 43 * ! 0 word ! 44 * !_______________________! 45 * ! Auxiliary ! 46 * ! vector ! 47 * ! 2 word entries ! 48 * ! ! 49 * !_______________________! 50 * ! 0 word ! 51 * !_______________________! 52 * ! Environment ! 53 * ! pointers ! 54 * ! ... ! 55 * ! (one word each) ! 56 * !_______________________! 57 * ! 0 word ! 58 * !_______________________! 59 * ! Argument ! low addresses 60 * ! pointers ! 61 * ! Argc words ! 62 * !_______________________! 63 * ! ! 64 * ! Argc ! 65 * !_______________________! <- %sp + 64 66 * ! ! 67 * ! Window save area ! 68 * !_______________________! <- %sp 69 */ 70 71#if defined(lint) 72 73extern unsigned long _setup(); 74extern void atexit_fini(); 75 76void 77main() 78{ 79 (void) _setup(); 80 atexit_fini(); 81} 82 83#else 84 85#include <sys/asm_linkage.h> 86#include <sys/param.h> 87#include <link.h> 88 89 .file "boot.s" 90 .seg ".text" 91 .global _rt_boot, _setup, atexit_fini 92 .type _rt_boot, #function 93 .align 4 94 95! Entry vector 96! +0: normal start 97! +4: compatibility start, now an error 98! +8: alias start (frame exists) 99 100_rt_boot: 101 ba,a _elf_start 102 ba,a _aout_start 103 ba,a _alias_start 104 105! Start up routines -- the aout_start will have a pointer in %o0 that we'll 106! want to save -- the elf can be zeroed. 107 108_elf_start: 109 clr %o0 ! 0 in %o0 == ELF 110_aout_start: ! (falls through) 111 112! Create a stack frame, perform PIC set up. If we're a "normal" start, we have 113! to determine a bunch of things from our "environment" and construct an ELF 114! boot attribute value vector. Otherwise, it's already been done and we can 115! skip it. 116 117 save %sp, -SA(MINFRAME + (EB_MAX * 8)), %sp 118_alias_start: 1191: ! PIC prologue 120 call 2f 121 sethi %hi(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 1222: 123 or %l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 124 125! If %i0 (was %o0) is non-zero, we're in compatibility and we can 126! skip construction of the ELF boot attribute vector. 127 128 addcc %i0, %g0, %o0 ! set condition codes 129 bne 1f ! if non-zero, skip setup 130 add %l7, %o7, %l7 ! finish PIC prologue 131 132! %fp points to the root of our ELF bootstrap vector, use it to construct 133! the vector and send it to _setup. 134 135 add %sp, SA(MINFRAME), %o0 ! &eb[0] == %sp + frame size 136 set EB_ARGV, %l0 ! code for this entry 137 st %l0, [%o0] ! store it 138 add %fp, 68, %l0 ! argument vector is at %fp+68 139 st %l0, [%o0 + 4] ! store that 140 ld [%fp + 64], %l1 ! get argument count 141 inc %l1 ! account for last element of 0 142 sll %l1, 2, %l1 ! multiply by 4 143 add %l0, %l1, %l0 ! and get address of first env ptr 144 st %l0, [%o0 + 12] ! store it in the vector 145 set EB_ENVP, %l1 ! code for environment base 146 st %l1, [%o0 + 8] ! store it 147 set EB_AUXV, %l1 ! get code for auxiliary vector 148 st %l1, [%o0 + 16] ! store it 1492: 150 ld [%l0], %l1 ! get an entry 151 tst %l1 ! are we at a "0" entry in environment? 152 bne 2b ! no, go back and look again 153 add %l0, 4, %l0 ! incrementing pointer in delay 154 st %l0, [%o0 + 20] ! store aux vector pointer 155 set EB_NULL, %l0 ! set up for the last pointer 156 st %l0, [%o0 + 24] ! and store it 157 158! Call _setup. Two arguments, the ELF bootstrap vector and our (unrelocated) 159! _DYNAMIC address. The _DYNAMIC address is located in entry 0 of the GOT 160 1611: 162 mov %g0, %g2 ! clear globals 163 mov %g0, %g3 164 call _setup ! call it 165 ld [%l7], %o1 ! 2nd parameter 166 167! On return, give callee the exit function in %g1, and either jump to the 168! target program (normal), or if return value of _setup is "0" we have 169! to return to the compatibility bootstrap. In either case, clear out 170! reserved globals. 171 172 ld [%l7 + atexit_fini], %g1! get function address 173 restore %o0, %g0, %l1 ! release frame 174 tst %l1 ! compatibility return? 175 be 1f ! yes, 176 mov %g0, %g4 ! but clear one last global in delay 177 jmpl %l1, %g0 ! call main program 178 nop 1791: 180 retl ! compatibility return 181 nop 182 183 .size _rt_boot, . - _rt_boot 184#endif 185