10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*11798SRoger.Faulkner@Sun.COM * Common Development and Distribution License (the "License"). 6*11798SRoger.Faulkner@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*11798SRoger.Faulkner@Sun.COM 220Sstevel@tonic-gate/* 23*11798SRoger.Faulkner@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*11798SRoger.Faulkner@Sun.COM * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate .file "_rtboot.s" 280Sstevel@tonic-gate 290Sstevel@tonic-gate! Bootstrap routine for alias ld.so. Control arrives here either directly 300Sstevel@tonic-gate! from exec() upon invocation of a dynamically linked program specifying our 310Sstevel@tonic-gate! alias as its interpreter. 320Sstevel@tonic-gate! 330Sstevel@tonic-gate! On entry, the stack appears as: 340Sstevel@tonic-gate! 350Sstevel@tonic-gate!_______________________! high addresses 360Sstevel@tonic-gate! ! 370Sstevel@tonic-gate! Information ! 380Sstevel@tonic-gate! Block ! 390Sstevel@tonic-gate! (size varies) ! 400Sstevel@tonic-gate!_______________________! 410Sstevel@tonic-gate! 0 word ! 420Sstevel@tonic-gate!_______________________! 430Sstevel@tonic-gate! Auxiliary ! 440Sstevel@tonic-gate! vector ! 450Sstevel@tonic-gate! 2 word entries ! 460Sstevel@tonic-gate! ! 470Sstevel@tonic-gate!_______________________! 480Sstevel@tonic-gate! 0 word ! 490Sstevel@tonic-gate!_______________________! 500Sstevel@tonic-gate! Environment ! 510Sstevel@tonic-gate! pointers ! 520Sstevel@tonic-gate! ... ! 530Sstevel@tonic-gate! (one word each) ! 540Sstevel@tonic-gate!_______________________! 550Sstevel@tonic-gate! 0 word ! 560Sstevel@tonic-gate!_______________________! 570Sstevel@tonic-gate! Argument ! low addresses 580Sstevel@tonic-gate! pointers ! 590Sstevel@tonic-gate! Argc words ! 600Sstevel@tonic-gate!_______________________! 610Sstevel@tonic-gate! ! 620Sstevel@tonic-gate! Argc ! 630Sstevel@tonic-gate!_______________________!<- %sp +64 640Sstevel@tonic-gate! ! 650Sstevel@tonic-gate! Window save area ! 660Sstevel@tonic-gate!_______________________! <- %sp 670Sstevel@tonic-gate 680Sstevel@tonic-gate#include <sys/asm_linkage.h> 690Sstevel@tonic-gate#include <sys/param.h> 700Sstevel@tonic-gate#include <sys/syscall.h> 710Sstevel@tonic-gate#include <link.h> 720Sstevel@tonic-gate#include "alias_boot.h" 730Sstevel@tonic-gate 740Sstevel@tonic-gate .section ".text" 750Sstevel@tonic-gate .volatile 760Sstevel@tonic-gate .global __rtboot 770Sstevel@tonic-gate .local __rtld 780Sstevel@tonic-gate .local s.LDSO, s.ZERO 79*11798SRoger.Faulkner@Sun.COM .local f.PANIC, f.OPENAT, f.MMAP, f.FSTATAT, f.SYSCONFIG 80*11798SRoger.Faulkner@Sun.COM .local f.CLOSE, f.EXIT, f.MUNMAP 810Sstevel@tonic-gate .type __rtboot, #function 820Sstevel@tonic-gate .align 4 830Sstevel@tonic-gate 840Sstevel@tonic-gate! Create a stack frame, perform PIC set up. If we're a "normal" start, we have 850Sstevel@tonic-gate! to determine a bunch of things from our "environment" and construct an ELF 860Sstevel@tonic-gate! boot attribute value vector. Otherwise, it's already been done and we can 870Sstevel@tonic-gate! skip it. 880Sstevel@tonic-gate 890Sstevel@tonic-gate__rtboot: 900Sstevel@tonic-gate save %sp, -SA(MINFRAME + (EB_MAX * 8) + ((S_MAX + F_MAX) * 4)), %sp 910Sstevel@tonic-gate1: ! PIC prologue 920Sstevel@tonic-gate call 2f ! get PIC for PIC work 930Sstevel@tonic-gate 940Sstevel@tonic-gate! Set up pointers to __rtld parameters. eb[], strings[] and funcs[] are on 950Sstevel@tonic-gate! the stack. Note that we will call ld.so with an entry vector that causes 960Sstevel@tonic-gate! it to use the stack frame we have. 970Sstevel@tonic-gate 980Sstevel@tonic-gate add %sp, MINFRAME, %o0 ! &eb[0] 990Sstevel@tonic-gate2: 1000Sstevel@tonic-gate add %o0, (EB_MAX * 8), %o1 ! &strings[0] == &eb[EB_MAX] 1010Sstevel@tonic-gate add %o1, (S_MAX * 4), %o2 ! &funcs[0] == &strings[S_MAX] 1020Sstevel@tonic-gate set EB_ARGV, %l0 ! code for this entry 1030Sstevel@tonic-gate st %l0, [%o0] ! store it 1040Sstevel@tonic-gate add %fp, 68, %l0 ! argument vector is at %fp+68 1050Sstevel@tonic-gate st %l0, [%o0 + 4] ! store that 1060Sstevel@tonic-gate ld [%fp + 64], %l1 ! get argument count 1070Sstevel@tonic-gate inc %l1 ! account for last element of 0 1080Sstevel@tonic-gate sll %l1, 2, %l1 ! multiply by 4 1090Sstevel@tonic-gate add %l0, %l1, %l0 ! and get address of first env ptr 1100Sstevel@tonic-gate st %l0, [%o0 + 12] ! store it in the vector 1110Sstevel@tonic-gate set EB_ENVP, %l1 ! code for environment base 1120Sstevel@tonic-gate st %l1, [%o0 + 8] ! store it 1130Sstevel@tonic-gate set EB_AUXV, %l1 ! get code for auxiliary vector 1140Sstevel@tonic-gate st %l1, [%o0 + 16] ! store it 1150Sstevel@tonic-gate2: 1160Sstevel@tonic-gate ld [%l0], %l1 ! get an entry 1170Sstevel@tonic-gate tst %l1 ! are we at a "0" entry in environment? 1180Sstevel@tonic-gate bne 2b ! no, go back and look again 1190Sstevel@tonic-gate add %l0, 4, %l0 ! incrementing pointer in delay 1200Sstevel@tonic-gate st %l0, [%o0 + 20] ! store aux vector pointer 1210Sstevel@tonic-gate set EB_NULL, %l0 ! set up for the last pointer 1220Sstevel@tonic-gate st %l0, [%o0 + 24] ! and store it 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate! Initialize strings and functions as appropriate 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate#define SI(n) \ 1270Sstevel@tonic-gate set (s./**/n - 1b), %l0; \ 1280Sstevel@tonic-gate add %o7, %l0, %l0; \ 1290Sstevel@tonic-gate st %l0, [%o1 + (n/**/_S * 4)] 1300Sstevel@tonic-gate#define FI(n) \ 1310Sstevel@tonic-gate set (f./**/n - 1b), %l0; \ 1320Sstevel@tonic-gate add %o7, %l0, %l0; \ 1330Sstevel@tonic-gate st %l0, [%o2 + (n/**/_F * 4)] 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate SI(LDSO) 1360Sstevel@tonic-gate SI(ZERO) 1370Sstevel@tonic-gate SI(EMPTY) 1380Sstevel@tonic-gate FI(PANIC) 139*11798SRoger.Faulkner@Sun.COM FI(OPENAT) 1400Sstevel@tonic-gate FI(MMAP) 141*11798SRoger.Faulkner@Sun.COM FI(FSTATAT) 1420Sstevel@tonic-gate FI(SYSCONFIG) 1430Sstevel@tonic-gate FI(CLOSE) 1440Sstevel@tonic-gate FI(MUNMAP) 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate! Call the startup function to get the real loader in here. 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate call __rtld ! call it 1490Sstevel@tonic-gate mov %o0, %l0 ! and save &eb[0] for later 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate! On return, jump to the function in %o0, passing &eb[0] in %o0 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate jmpl %o0, %g0 ! call main program 1540Sstevel@tonic-gate mov %l0, %i0 ! set up parameter 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate! Functions 1570Sstevel@tonic-gate 1580Sstevel@tonic-gatef.PANIC: 1590Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp ! make a frame 1600Sstevel@tonic-gate mov %i0, %o1 ! set up pointer 1610Sstevel@tonic-gate clr %o2 ! set up character counter 1620Sstevel@tonic-gate1: ! loop over all characters 1630Sstevel@tonic-gate ldub [%i0 + %o2], %o0 ! get byte 1640Sstevel@tonic-gate tst %o0 ! end of string? 1650Sstevel@tonic-gate bne,a 1b ! no, 1660Sstevel@tonic-gate inc %o2 ! increment count 1670Sstevel@tonic-gate call f.WRITE ! write(2, buf, %o2) 1680Sstevel@tonic-gate mov 2, %o0 1690Sstevel@tonic-gate2: 1700Sstevel@tonic-gate call 1f ! get PC 1710Sstevel@tonic-gate mov l.ERROR, %o2 ! same with constant message 1720Sstevel@tonic-gate1: 1730Sstevel@tonic-gate set (s.ERROR - 2b), %o1 ! get PC-relative address 1740Sstevel@tonic-gate add %o7, %o1, %o1 ! and now make it absolute 1750Sstevel@tonic-gate call f.WRITE ! write it out 1760Sstevel@tonic-gate mov 2, %o0 ! to standard error 1770Sstevel@tonic-gate ba f.EXIT ! leave 1780Sstevel@tonic-gate nop 1790Sstevel@tonic-gate 180*11798SRoger.Faulkner@Sun.COMf.OPENAT: 1810Sstevel@tonic-gate ba __syscall 182*11798SRoger.Faulkner@Sun.COM mov SYS_openat, %g1 1830Sstevel@tonic-gate 1840Sstevel@tonic-gatef.MMAP: 1850Sstevel@tonic-gate sethi %hi(0x80000000), %g1 ! MAP_NEW 1860Sstevel@tonic-gate or %g1, %o3, %o3 1870Sstevel@tonic-gate ba __syscall 1880Sstevel@tonic-gate mov SYS_mmap, %g1 1890Sstevel@tonic-gate 1900Sstevel@tonic-gatef.MUNMAP: 1910Sstevel@tonic-gate ba __syscall 1920Sstevel@tonic-gate mov SYS_munmap, %g1 1930Sstevel@tonic-gate 1940Sstevel@tonic-gatef.READ: 1950Sstevel@tonic-gate ba __syscall 1960Sstevel@tonic-gate mov SYS_read, %g1 1970Sstevel@tonic-gate 1980Sstevel@tonic-gatef.WRITE: 1990Sstevel@tonic-gate ba __syscall 2000Sstevel@tonic-gate mov SYS_write, %g1 2010Sstevel@tonic-gate 2020Sstevel@tonic-gatef.LSEEK: 2030Sstevel@tonic-gate ba __syscall 2040Sstevel@tonic-gate mov SYS_lseek, %g1 2050Sstevel@tonic-gate 2060Sstevel@tonic-gatef.CLOSE: 2070Sstevel@tonic-gate ba __syscall 2080Sstevel@tonic-gate mov SYS_close, %g1 2090Sstevel@tonic-gate 210*11798SRoger.Faulkner@Sun.COMf.FSTATAT: 2110Sstevel@tonic-gate ba __syscall 212*11798SRoger.Faulkner@Sun.COM mov SYS_fstatat, %g1 2130Sstevel@tonic-gate 2140Sstevel@tonic-gatef.SYSCONFIG: 2150Sstevel@tonic-gate ba __syscall 2160Sstevel@tonic-gate mov SYS_sysconfig, %g1 2170Sstevel@tonic-gate 2180Sstevel@tonic-gatef.EXIT: 2190Sstevel@tonic-gate mov SYS_exit, %g1 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate__syscall: 2220Sstevel@tonic-gate t 0x8 ! call the system call 2230Sstevel@tonic-gate bcs __err_exit ! test for error 2240Sstevel@tonic-gate nop 2250Sstevel@tonic-gate retl ! return 2260Sstevel@tonic-gate nop 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate__err_exit: 2290Sstevel@tonic-gate retl ! return 2300Sstevel@tonic-gate mov -1, %o0 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate! String constants 2330Sstevel@tonic-gate 2340Sstevel@tonic-gates.LDSO: .asciz "/usr/lib/ld.so.1" 2350Sstevel@tonic-gates.ZERO: .asciz "/dev/zero" 2360Sstevel@tonic-gates.EMPTY:.asciz "(null)" 2370Sstevel@tonic-gates.ERROR:.asciz ": no (or bad) /usr/lib/ld.so.1\n" 2380Sstevel@tonic-gatel.ERROR= . - s.ERROR 2390Sstevel@tonic-gate .align 4 2400Sstevel@tonic-gate .size __rtboot, . - __rtboot 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate! During construction -- the assembly output of _rtld.c2s is placed here. 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate .section ".text" 2450Sstevel@tonic-gate .nonvolatile 246