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