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