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