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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright (c) 2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27#ident "%Z%%M% %I% %E% SMI" 28 29 .file "_rtboot.s" 30 31! Bootstrap routine for alias ld.so. Control arrives here either directly 32! from exec() upon invocation of a dynamically linked program specifying our 33! alias 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#include <sys/asm_linkage.h> 71#include <sys/param.h> 72#include <sys/syscall.h> 73#include <link.h> 74#include "alias_boot.h" 75 76 .section ".text" 77 .volatile 78 .global __rtboot 79 .local __rtld 80 .local s.LDSO, s.ZERO 81 .local f.PANIC, f.OPEN, f.MMAP, f.FSTAT, f.SYSCONFIG, f.CLOSE, f.EXIT 82 .local f.MUNMAP 83 .type __rtboot, #function 84 .align 4 85 86! Create a stack frame, perform PIC set up. If we're a "normal" start, we have 87! to determine a bunch of things from our "environment" and construct an ELF 88! boot attribute value vector. Otherwise, it's already been done and we can 89! skip it. 90 91__rtboot: 92 save %sp, -SA(MINFRAME + (EB_MAX * 8) + ((S_MAX + F_MAX) * 4)), %sp 931: ! PIC prologue 94 call 2f ! get PIC for PIC work 95 96! Set up pointers to __rtld parameters. eb[], strings[] and funcs[] are on 97! the stack. Note that we will call ld.so with an entry vector that causes 98! it to use the stack frame we have. 99 100 add %sp, MINFRAME, %o0 ! &eb[0] 1012: 102 add %o0, (EB_MAX * 8), %o1 ! &strings[0] == &eb[EB_MAX] 103 add %o1, (S_MAX * 4), %o2 ! &funcs[0] == &strings[S_MAX] 104 set EB_ARGV, %l0 ! code for this entry 105 st %l0, [%o0] ! store it 106 add %fp, 68, %l0 ! argument vector is at %fp+68 107 st %l0, [%o0 + 4] ! store that 108 ld [%fp + 64], %l1 ! get argument count 109 inc %l1 ! account for last element of 0 110 sll %l1, 2, %l1 ! multiply by 4 111 add %l0, %l1, %l0 ! and get address of first env ptr 112 st %l0, [%o0 + 12] ! store it in the vector 113 set EB_ENVP, %l1 ! code for environment base 114 st %l1, [%o0 + 8] ! store it 115 set EB_AUXV, %l1 ! get code for auxiliary vector 116 st %l1, [%o0 + 16] ! store it 1172: 118 ld [%l0], %l1 ! get an entry 119 tst %l1 ! are we at a "0" entry in environment? 120 bne 2b ! no, go back and look again 121 add %l0, 4, %l0 ! incrementing pointer in delay 122 st %l0, [%o0 + 20] ! store aux vector pointer 123 set EB_NULL, %l0 ! set up for the last pointer 124 st %l0, [%o0 + 24] ! and store it 125 126! Initialize strings and functions as appropriate 127 128#define SI(n) \ 129 set (s./**/n - 1b), %l0; \ 130 add %o7, %l0, %l0; \ 131 st %l0, [%o1 + (n/**/_S * 4)] 132#define FI(n) \ 133 set (f./**/n - 1b), %l0; \ 134 add %o7, %l0, %l0; \ 135 st %l0, [%o2 + (n/**/_F * 4)] 136 137 SI(LDSO) 138 SI(ZERO) 139 SI(EMPTY) 140 FI(PANIC) 141 FI(OPEN) 142 FI(MMAP) 143 FI(FSTAT) 144 FI(SYSCONFIG) 145 FI(CLOSE) 146 FI(MUNMAP) 147 148! Call the startup function to get the real loader in here. 149 150 call __rtld ! call it 151 mov %o0, %l0 ! and save &eb[0] for later 152 153! On return, jump to the function in %o0, passing &eb[0] in %o0 154 155 jmpl %o0, %g0 ! call main program 156 mov %l0, %i0 ! set up parameter 157 158! Functions 159 160f.PANIC: 161 save %sp, -SA(MINFRAME), %sp ! make a frame 162 mov %i0, %o1 ! set up pointer 163 clr %o2 ! set up character counter 1641: ! loop over all characters 165 ldub [%i0 + %o2], %o0 ! get byte 166 tst %o0 ! end of string? 167 bne,a 1b ! no, 168 inc %o2 ! increment count 169 call f.WRITE ! write(2, buf, %o2) 170 mov 2, %o0 1712: 172 call 1f ! get PC 173 mov l.ERROR, %o2 ! same with constant message 1741: 175 set (s.ERROR - 2b), %o1 ! get PC-relative address 176 add %o7, %o1, %o1 ! and now make it absolute 177 call f.WRITE ! write it out 178 mov 2, %o0 ! to standard error 179 ba f.EXIT ! leave 180 nop 181 182f.OPEN: 183 ba __syscall 184 mov SYS_open, %g1 185 186f.MMAP: 187 sethi %hi(0x80000000), %g1 ! MAP_NEW 188 or %g1, %o3, %o3 189 ba __syscall 190 mov SYS_mmap, %g1 191 192f.MUNMAP: 193 ba __syscall 194 mov SYS_munmap, %g1 195 196f.READ: 197 ba __syscall 198 mov SYS_read, %g1 199 200f.WRITE: 201 ba __syscall 202 mov SYS_write, %g1 203 204f.LSEEK: 205 ba __syscall 206 mov SYS_lseek, %g1 207 208f.CLOSE: 209 ba __syscall 210 mov SYS_close, %g1 211 212f.FSTAT: 213 ba __syscall 214 mov SYS_fstat, %g1 215 216f.SYSCONFIG: 217 ba __syscall 218 mov SYS_sysconfig, %g1 219 220f.EXIT: 221 mov SYS_exit, %g1 222 223__syscall: 224 t 0x8 ! call the system call 225 bcs __err_exit ! test for error 226 nop 227 retl ! return 228 nop 229 230__err_exit: 231 retl ! return 232 mov -1, %o0 233 234! String constants 235 236s.LDSO: .asciz "/usr/lib/ld.so.1" 237s.ZERO: .asciz "/dev/zero" 238s.EMPTY:.asciz "(null)" 239s.ERROR:.asciz ": no (or bad) /usr/lib/ld.so.1\n" 240l.ERROR= . - s.ERROR 241 .align 4 242 .size __rtboot, . - __rtboot 243 244! During construction -- the assembly output of _rtld.c2s is placed here. 245 246 .section ".text" 247 .nonvolatile 248