xref: /illumos-gate/usr/src/lib/libc/sparc/crt/_rtboot.S (revision 5d9d9091)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
58fd04b83SRoger A. Faulkner * Common Development and Distribution License (the "License").
68fd04b83SRoger A. Faulkner * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
218fd04b83SRoger A. Faulkner
227c478bd9Sstevel@tonic-gate/*
238fd04b83SRoger A. Faulkner * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
248fd04b83SRoger A. Faulkner * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate	.file	"_rtboot.s"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate! Bootstrap routine for alias ld.so.  Control arrives here either directly
307c478bd9Sstevel@tonic-gate! from exec() upon invocation of a dynamically linked program specifying our
317c478bd9Sstevel@tonic-gate! alias as its interpreter.
327c478bd9Sstevel@tonic-gate!
337c478bd9Sstevel@tonic-gate! On entry, the stack appears as:
347c478bd9Sstevel@tonic-gate!
357c478bd9Sstevel@tonic-gate!_______________________!  high addresses
36*5d9d9091SRichard Lowe!			!
37*5d9d9091SRichard Lowe!	Information	!
38*5d9d9091SRichard Lowe!	Block		!
39*5d9d9091SRichard Lowe!	(size varies)	!
407c478bd9Sstevel@tonic-gate!_______________________!
417c478bd9Sstevel@tonic-gate!	0 word		!
427c478bd9Sstevel@tonic-gate!_______________________!
437c478bd9Sstevel@tonic-gate!	Auxiliary	!
447c478bd9Sstevel@tonic-gate!	vector		!
457c478bd9Sstevel@tonic-gate!	2 word entries	!
467c478bd9Sstevel@tonic-gate!			!
477c478bd9Sstevel@tonic-gate!_______________________!
487c478bd9Sstevel@tonic-gate!	0 word		!
497c478bd9Sstevel@tonic-gate!_______________________!
507c478bd9Sstevel@tonic-gate!	Environment	!
517c478bd9Sstevel@tonic-gate!	pointers	!
527c478bd9Sstevel@tonic-gate!	...		!
537c478bd9Sstevel@tonic-gate!	(one word each)	!
547c478bd9Sstevel@tonic-gate!_______________________!
557c478bd9Sstevel@tonic-gate!	0 word		!
567c478bd9Sstevel@tonic-gate!_______________________!
577c478bd9Sstevel@tonic-gate!	Argument	! low addresses
587c478bd9Sstevel@tonic-gate!	pointers	!
597c478bd9Sstevel@tonic-gate!	Argc words	!
607c478bd9Sstevel@tonic-gate!_______________________!
617c478bd9Sstevel@tonic-gate!			!
627c478bd9Sstevel@tonic-gate!	Argc		!
637c478bd9Sstevel@tonic-gate!_______________________!<- %sp +64
647c478bd9Sstevel@tonic-gate!			!
65*5d9d9091SRichard Lowe!   Window save area	!
667c478bd9Sstevel@tonic-gate!_______________________! <- %sp
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
697c478bd9Sstevel@tonic-gate#include <sys/param.h>
707c478bd9Sstevel@tonic-gate#include <sys/syscall.h>
717c478bd9Sstevel@tonic-gate#include <link.h>
727c478bd9Sstevel@tonic-gate#include "alias_boot.h"
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate	.section ".text"
757c478bd9Sstevel@tonic-gate	.volatile
767c478bd9Sstevel@tonic-gate	.global	__rtboot
776a3e8e86SRichard Lowe	.global	__rtld
787c478bd9Sstevel@tonic-gate	.local	s.LDSO, s.ZERO
798fd04b83SRoger A. Faulkner	.local	f.PANIC, f.OPENAT, f.MMAP, f.FSTATAT, f.SYSCONFIG
808fd04b83SRoger A. Faulkner	.local	f.CLOSE, f.EXIT, f.MUNMAP
817c478bd9Sstevel@tonic-gate	.type	__rtboot, #function
827c478bd9Sstevel@tonic-gate	.align	4
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate! Create a stack frame, perform PIC set up.  If we're a "normal" start, we have
857c478bd9Sstevel@tonic-gate! to determine a bunch of things from our "environment" and construct an ELF
867c478bd9Sstevel@tonic-gate! boot attribute value vector.  Otherwise, it's already been done and we can
877c478bd9Sstevel@tonic-gate! skip it.
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate__rtboot:
907c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + (EB_MAX * 8) + ((S_MAX + F_MAX) * 4)), %sp
917c478bd9Sstevel@tonic-gate1:					! PIC prologue
927c478bd9Sstevel@tonic-gate	call	2f			! get PIC for PIC work
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate! Set up pointers to __rtld parameters.  eb[], strings[] and funcs[] are on
957c478bd9Sstevel@tonic-gate! the stack.  Note that we will call ld.so with an entry vector that causes
967c478bd9Sstevel@tonic-gate! it to use the stack frame we have.
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate	add	%sp, MINFRAME, %o0	! &eb[0]
997c478bd9Sstevel@tonic-gate2:
1007c478bd9Sstevel@tonic-gate	add	%o0, (EB_MAX * 8), %o1	! &strings[0] == &eb[EB_MAX]
1017c478bd9Sstevel@tonic-gate	add	%o1, (S_MAX * 4), %o2	! &funcs[0] == &strings[S_MAX]
1027c478bd9Sstevel@tonic-gate	set	EB_ARGV, %l0		! code for this entry
1037c478bd9Sstevel@tonic-gate	st	%l0, [%o0]		!   store it
1047c478bd9Sstevel@tonic-gate	add	%fp, 68, %l0		! argument vector is at %fp+68
1057c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 4]		!   store that
1067c478bd9Sstevel@tonic-gate	ld	[%fp + 64], %l1		! get argument count
1077c478bd9Sstevel@tonic-gate	inc	%l1			! account for last element of 0
1087c478bd9Sstevel@tonic-gate	sll	%l1, 2, %l1		! multiply by 4
1097c478bd9Sstevel@tonic-gate	add	%l0, %l1, %l0		!   and get address of first env ptr
1107c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 12]		! store it in the vector
1117c478bd9Sstevel@tonic-gate	set	EB_ENVP, %l1		! code for environment base
1127c478bd9Sstevel@tonic-gate	st	%l1, [%o0 + 8]		!   store it
1137c478bd9Sstevel@tonic-gate	set	EB_AUXV, %l1		! get code for auxiliary vector
1147c478bd9Sstevel@tonic-gate	st	%l1, [%o0 + 16]		!   store it
1157c478bd9Sstevel@tonic-gate2:
1167c478bd9Sstevel@tonic-gate	ld	[%l0], %l1		! get an entry
1177c478bd9Sstevel@tonic-gate	tst	%l1			! are we at a "0" entry in environment?
1187c478bd9Sstevel@tonic-gate	bne	2b			!   no, go back and look again
1197c478bd9Sstevel@tonic-gate	add	%l0, 4, %l0		!     incrementing pointer in delay
1207c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 20]		! store aux vector pointer
1217c478bd9Sstevel@tonic-gate	set	EB_NULL, %l0		! set up for the last pointer
1227c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 24]		!   and store it
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate! Initialize strings and functions as appropriate
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate#define	SI(n) \
127*5d9d9091SRichard Lowe	set	(s.##n  - 1b), %l0; \
1287c478bd9Sstevel@tonic-gate	add	%o7, %l0, %l0; \
129*5d9d9091SRichard Lowe	st	%l0, [%o1 + (n##_S * 4)]
1307c478bd9Sstevel@tonic-gate#define	FI(n) \
131*5d9d9091SRichard Lowe	set	(f.##n - 1b), %l0; \
1327c478bd9Sstevel@tonic-gate	add	%o7, %l0, %l0; \
133*5d9d9091SRichard Lowe	st	%l0, [%o2 + (n##_F * 4)]
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate	SI(LDSO)
1367c478bd9Sstevel@tonic-gate	SI(ZERO)
1377c478bd9Sstevel@tonic-gate	SI(EMPTY)
1387c478bd9Sstevel@tonic-gate	FI(PANIC)
1398fd04b83SRoger A. Faulkner	FI(OPENAT)
1407c478bd9Sstevel@tonic-gate	FI(MMAP)
1418fd04b83SRoger A. Faulkner	FI(FSTATAT)
1427c478bd9Sstevel@tonic-gate	FI(SYSCONFIG)
1437c478bd9Sstevel@tonic-gate	FI(CLOSE)
1447c478bd9Sstevel@tonic-gate	FI(MUNMAP)
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate! Call the startup function to get the real loader in here.
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate	call	__rtld			! call it
1497c478bd9Sstevel@tonic-gate	mov	%o0, %l0		!   and save &eb[0] for later
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate! On return, jump to the function in %o0, passing &eb[0] in %o0
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate	jmpl	%o0, %g0		! call main program
1547c478bd9Sstevel@tonic-gate	mov	%l0, %i0		! set up parameter
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate! Functions
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gatef.PANIC:
1597c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp	! make a frame
1607c478bd9Sstevel@tonic-gate	mov	%i0, %o1		! set up pointer
1617c478bd9Sstevel@tonic-gate	clr	%o2			! set up character counter
1627c478bd9Sstevel@tonic-gate1:					! loop over all characters
1637c478bd9Sstevel@tonic-gate	ldub	[%i0 + %o2], %o0	! get byte
1647c478bd9Sstevel@tonic-gate	tst	%o0			! end of string?
1657c478bd9Sstevel@tonic-gate	bne,a	1b			!   no,
1667c478bd9Sstevel@tonic-gate	inc	%o2			!     increment count
1677c478bd9Sstevel@tonic-gate	call	f.WRITE			! write(2, buf, %o2)
1687c478bd9Sstevel@tonic-gate	mov	2, %o0
1697c478bd9Sstevel@tonic-gate2:
1707c478bd9Sstevel@tonic-gate	call	1f			! get PC
1717c478bd9Sstevel@tonic-gate	mov	l.ERROR, %o2		! same with constant message
1727c478bd9Sstevel@tonic-gate1:
173*5d9d9091SRichard Lowe	set	(s.ERROR - 2b), %o1	! get PC-relative address
1747c478bd9Sstevel@tonic-gate	add	%o7, %o1, %o1		!   and now make it absolute
1757c478bd9Sstevel@tonic-gate	call	f.WRITE			! write it out
1767c478bd9Sstevel@tonic-gate	mov	2, %o0			!   to standard error
1777c478bd9Sstevel@tonic-gate	ba	f.EXIT			! leave
1787c478bd9Sstevel@tonic-gate	nop
1797c478bd9Sstevel@tonic-gate
1808fd04b83SRoger A. Faulknerf.OPENAT:
1817c478bd9Sstevel@tonic-gate	ba	__syscall
1828fd04b83SRoger A. Faulkner	mov	SYS_openat, %g1
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gatef.MMAP:
1857c478bd9Sstevel@tonic-gate	sethi	%hi(0x80000000), %g1	! MAP_NEW
1867c478bd9Sstevel@tonic-gate	or	%g1, %o3, %o3
1877c478bd9Sstevel@tonic-gate	ba	__syscall
1887c478bd9Sstevel@tonic-gate	mov	SYS_mmap, %g1
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gatef.MUNMAP:
1917c478bd9Sstevel@tonic-gate	ba	__syscall
1927c478bd9Sstevel@tonic-gate	mov	SYS_munmap, %g1
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gatef.READ:
1957c478bd9Sstevel@tonic-gate	ba	__syscall
1967c478bd9Sstevel@tonic-gate	mov	SYS_read, %g1
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gatef.WRITE:
1997c478bd9Sstevel@tonic-gate	ba	__syscall
2007c478bd9Sstevel@tonic-gate	mov	SYS_write, %g1
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gatef.LSEEK:
2037c478bd9Sstevel@tonic-gate	ba	__syscall
2047c478bd9Sstevel@tonic-gate	mov	SYS_lseek, %g1
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gatef.CLOSE:
2077c478bd9Sstevel@tonic-gate	ba	__syscall
2087c478bd9Sstevel@tonic-gate	mov	SYS_close, %g1
2097c478bd9Sstevel@tonic-gate
2108fd04b83SRoger A. Faulknerf.FSTATAT:
2117c478bd9Sstevel@tonic-gate	ba	__syscall
2128fd04b83SRoger A. Faulkner	mov	SYS_fstatat, %g1
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gatef.SYSCONFIG:
2157c478bd9Sstevel@tonic-gate	ba	__syscall
2167c478bd9Sstevel@tonic-gate	mov	SYS_sysconfig, %g1
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gatef.EXIT:
2197c478bd9Sstevel@tonic-gate	mov	SYS_exit, %g1
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate__syscall:
2227c478bd9Sstevel@tonic-gate	t	0x8			! call the system call
2237c478bd9Sstevel@tonic-gate	bcs	__err_exit		! test for error
2247c478bd9Sstevel@tonic-gate	nop
2257c478bd9Sstevel@tonic-gate	retl				! return
2267c478bd9Sstevel@tonic-gate	nop
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate__err_exit:
2297c478bd9Sstevel@tonic-gate	retl				! return
2307c478bd9Sstevel@tonic-gate	mov	-1, %o0
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate! String constants
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gates.LDSO:	.asciz	"/usr/lib/ld.so.1"
2357c478bd9Sstevel@tonic-gates.ZERO:	.asciz	"/dev/zero"
2367c478bd9Sstevel@tonic-gates.EMPTY:.asciz	"(null)"
2377c478bd9Sstevel@tonic-gates.ERROR:.asciz	": no (or bad) /usr/lib/ld.so.1\n"
2387c478bd9Sstevel@tonic-gatel.ERROR= . - s.ERROR
2397c478bd9Sstevel@tonic-gate	.align	4
2407c478bd9Sstevel@tonic-gate	.size	__rtboot, . - __rtboot
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate! During construction -- the assembly output of _rtld.c2s is placed here.
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate	.section ".text"
2457c478bd9Sstevel@tonic-gate	.nonvolatile
246