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