xref: /onnv-gate/usr/src/lib/libc/sparc/crt/_rtboot.s (revision 11798:1e7f1f154004)
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