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 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .file "_rtboot.s" 28 29! Bootstrap routine for alias ld.so. Control arrives here either directly 30! from exec() upon invocation of a dynamically linked program specifying our 31! alias as its interpreter. 32! 33! On entry, the stack appears as: 34! 35!_______________________! high addresses 36! ! 37! Information ! 38! Block ! 39! (size varies) ! 40!_______________________! 41! 0 word ! 42!_______________________! 43! Auxiliary ! 44! vector ! 45! 2 word entries ! 46! ! 47!_______________________! 48! 0 word ! 49!_______________________! 50! Environment ! 51! pointers ! 52! ... ! 53! (one word each) ! 54!_______________________! 55! 0 word ! 56!_______________________! 57! Argument ! low addresses 58! pointers ! 59! Argc words ! 60!_______________________! 61! ! 62! Argc ! 63!_______________________!<- %sp +64 64! ! 65! Window save area ! 66!_______________________! <- %sp 67 68#include <sys/asm_linkage.h> 69#include <sys/param.h> 70#include <sys/syscall.h> 71#include <link.h> 72#include "alias_boot.h" 73 74 .section ".text" 75 .volatile 76 .global __rtboot 77 .local __rtld 78 .local s.LDSO, s.ZERO 79 .local f.PANIC, f.OPENAT, f.MMAP, f.FSTATAT, f.SYSCONFIG 80 .local f.CLOSE, f.EXIT, f.MUNMAP 81 .type __rtboot, #function 82 .align 4 83 84! Create a stack frame, perform PIC set up. If we're a "normal" start, we have 85! to determine a bunch of things from our "environment" and construct an ELF 86! boot attribute value vector. Otherwise, it's already been done and we can 87! skip it. 88 89__rtboot: 90 save %sp, -SA(MINFRAME + (EB_MAX * 8) + ((S_MAX + F_MAX) * 4)), %sp 911: ! PIC prologue 92 call 2f ! get PIC for PIC work 93 94! Set up pointers to __rtld parameters. eb[], strings[] and funcs[] are on 95! the stack. Note that we will call ld.so with an entry vector that causes 96! it to use the stack frame we have. 97 98 add %sp, MINFRAME, %o0 ! &eb[0] 992: 100 add %o0, (EB_MAX * 8), %o1 ! &strings[0] == &eb[EB_MAX] 101 add %o1, (S_MAX * 4), %o2 ! &funcs[0] == &strings[S_MAX] 102 set EB_ARGV, %l0 ! code for this entry 103 st %l0, [%o0] ! store it 104 add %fp, 68, %l0 ! argument vector is at %fp+68 105 st %l0, [%o0 + 4] ! store that 106 ld [%fp + 64], %l1 ! get argument count 107 inc %l1 ! account for last element of 0 108 sll %l1, 2, %l1 ! multiply by 4 109 add %l0, %l1, %l0 ! and get address of first env ptr 110 st %l0, [%o0 + 12] ! store it in the vector 111 set EB_ENVP, %l1 ! code for environment base 112 st %l1, [%o0 + 8] ! store it 113 set EB_AUXV, %l1 ! get code for auxiliary vector 114 st %l1, [%o0 + 16] ! store it 1152: 116 ld [%l0], %l1 ! get an entry 117 tst %l1 ! are we at a "0" entry in environment? 118 bne 2b ! no, go back and look again 119 add %l0, 4, %l0 ! incrementing pointer in delay 120 st %l0, [%o0 + 20] ! store aux vector pointer 121 set EB_NULL, %l0 ! set up for the last pointer 122 st %l0, [%o0 + 24] ! and store it 123 124! Initialize strings and functions as appropriate 125 126#define SI(n) \ 127 set (s./**/n - 1b), %l0; \ 128 add %o7, %l0, %l0; \ 129 st %l0, [%o1 + (n/**/_S * 4)] 130#define FI(n) \ 131 set (f./**/n - 1b), %l0; \ 132 add %o7, %l0, %l0; \ 133 st %l0, [%o2 + (n/**/_F * 4)] 134 135 SI(LDSO) 136 SI(ZERO) 137 SI(EMPTY) 138 FI(PANIC) 139 FI(OPENAT) 140 FI(MMAP) 141 FI(FSTATAT) 142 FI(SYSCONFIG) 143 FI(CLOSE) 144 FI(MUNMAP) 145 146! Call the startup function to get the real loader in here. 147 148 call __rtld ! call it 149 mov %o0, %l0 ! and save &eb[0] for later 150 151! On return, jump to the function in %o0, passing &eb[0] in %o0 152 153 jmpl %o0, %g0 ! call main program 154 mov %l0, %i0 ! set up parameter 155 156! Functions 157 158f.PANIC: 159 save %sp, -SA(MINFRAME), %sp ! make a frame 160 mov %i0, %o1 ! set up pointer 161 clr %o2 ! set up character counter 1621: ! loop over all characters 163 ldub [%i0 + %o2], %o0 ! get byte 164 tst %o0 ! end of string? 165 bne,a 1b ! no, 166 inc %o2 ! increment count 167 call f.WRITE ! write(2, buf, %o2) 168 mov 2, %o0 1692: 170 call 1f ! get PC 171 mov l.ERROR, %o2 ! same with constant message 1721: 173 set (s.ERROR - 2b), %o1 ! get PC-relative address 174 add %o7, %o1, %o1 ! and now make it absolute 175 call f.WRITE ! write it out 176 mov 2, %o0 ! to standard error 177 ba f.EXIT ! leave 178 nop 179 180f.OPENAT: 181 ba __syscall 182 mov SYS_openat, %g1 183 184f.MMAP: 185 sethi %hi(0x80000000), %g1 ! MAP_NEW 186 or %g1, %o3, %o3 187 ba __syscall 188 mov SYS_mmap, %g1 189 190f.MUNMAP: 191 ba __syscall 192 mov SYS_munmap, %g1 193 194f.READ: 195 ba __syscall 196 mov SYS_read, %g1 197 198f.WRITE: 199 ba __syscall 200 mov SYS_write, %g1 201 202f.LSEEK: 203 ba __syscall 204 mov SYS_lseek, %g1 205 206f.CLOSE: 207 ba __syscall 208 mov SYS_close, %g1 209 210f.FSTATAT: 211 ba __syscall 212 mov SYS_fstatat, %g1 213 214f.SYSCONFIG: 215 ba __syscall 216 mov SYS_sysconfig, %g1 217 218f.EXIT: 219 mov SYS_exit, %g1 220 221__syscall: 222 t 0x8 ! call the system call 223 bcs __err_exit ! test for error 224 nop 225 retl ! return 226 nop 227 228__err_exit: 229 retl ! return 230 mov -1, %o0 231 232! String constants 233 234s.LDSO: .asciz "/usr/lib/ld.so.1" 235s.ZERO: .asciz "/dev/zero" 236s.EMPTY:.asciz "(null)" 237s.ERROR:.asciz ": no (or bad) /usr/lib/ld.so.1\n" 238l.ERROR= . - s.ERROR 239 .align 4 240 .size __rtboot, . - __rtboot 241 242! During construction -- the assembly output of _rtld.c2s is placed here. 243 244 .section ".text" 245 .nonvolatile 246