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 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 * ! 0 word ! 39 * !_______________________! 40 * ! ! 41 * ! Information ! 42 * ! Block ! 43 * ! (size varies) ! 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 + STACK_BIAS + WINDOWSIZE 66 * ! ! 67 * ! Window save area ! 68 * !_______________________! <- %sp + STACK_BIAS 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: normal start 98! +8: alias start (frame exists) XX64 what's this for? 99 100_rt_boot: 101 nop 102 ba,a _elf_start 103 ba,a _alias_start 104 105! Start up routines 106 107_elf_start: 108 109! Create a stack frame, perform PIC set up. We have 110! to determine a bunch of things from our "environment" and 111! construct an Elf64_Boot attribute value vector. 112 113 save %sp, -SA(MINFRAME + (EB_MAX * 16)), %sp 114 115_alias_start: 116 1171: ! PIC prologue 118 call 2f 119 sethi %hh(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1 1202: or %g1, %hm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1 121 sllx %g1, 32, %g5 122 sethi %lm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 123 or %l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7 124 or %g5, %l7, %l7 125 add %l7, %o7, %l7 ! finish PIC prologue 126 127! %fp points to the root of our ELF bootstrap vector, use it to construct 128! the vector and send it to _setup. 129! 130! The resulting Elf64_Boot vector looks like this: 131! 132! Offset Contents 133! +0x0 EB_ARGV 134! +0x8 argv[] 135! +0x10 EB_ENVP 136! +0x18 envp[] 137! +0x20 EB_AUXV 138! +0x28 auxv[] 139! +0x30 EB_NULL 140 141 add %sp, STACK_BIAS + SA(MINFRAME), %o0 142 ! &eb[0] == %sp + frame size 143 mov EB_ARGV, %l0 ! code for this entry 144 stx %l0, [%o0] ! store it 145 add %fp, WINDOWSIZE + 8 + STACK_BIAS, %l0 146 ! argument vector 147 stx %l0, [%o0 + 0x8] ! store that 148 ldx [%fp + WINDOWSIZE + STACK_BIAS], %l1 149 ! get argument count (argc) 150 inc %l1 ! account for last element of 0 151 sllx %l1, 3, %l1 ! multiply by 8 152 add %l0, %l1, %l0 ! and get address of first env ptr 153 stx %l0, [%o0 + 0x18] ! store it in the vector 154 mov EB_ENVP, %l1 ! code for environment base 155 stx %l1, [%o0 + 0x10] ! store it 156 mov EB_AUXV, %l1 ! get code for auxiliary vector 157 stx %l1, [%o0 + 0x20] ! store it 158 1593: ldx [%l0], %l1 ! get an entry 160 brnz,pt %l1, 3b ! if not at end, go back and look again 161 add %l0, 8, %l0 ! incrementing pointer in delay 162 stx %l0, [%o0 + 0x28] ! store aux vector pointer 163 164 mov EB_NULL, %l0 ! set up for the last pointer 165 stx %l0, [%o0 + 0x30] ! and store it 166 mov %g0, %g2 ! clear globals 167 mov %g0, %g3 168 169! Call _setup. Two arguments, the ELF bootstrap vector and our (unrelocated) 170! _DYNAMIC address. The _DYNAMIC address is located in entry 0 of the GOT 171 172 173 call _setup ! call it 174 ldx [%l7], %o1 175 176! On return, give callee the exit function in %g1, and jump to the 177! target program, clearing out the reserved globals as we go. 178 179 ldx [%l7 + atexit_fini], %g1! get function address 180 restore %o0, %g0, %l1 ! release frame 181 jmpl %l1, %g0 ! call main program 182 mov %g0, %g4 ! clear one last global in delay 183 184 .size _rt_boot, . - _rt_boot 185#endif 186