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