xref: /illumos-gate/usr/src/cmd/sgs/rtld/sparc/boot.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 (c) 1988 AT&T
24*5d9d9091SRichard Lowe *	  All Rights Reserved
25*5d9d9091SRichard Lowe *
26*5d9d9091SRichard Lowe * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
27*5d9d9091SRichard Lowe * Use is subject to license terms.
28*5d9d9091SRichard Lowe */
29*5d9d9091SRichard Lowe
30*5d9d9091SRichard Lowe/*
31*5d9d9091SRichard Lowe * Bootstrap routine for ld.so.  Control arrives here either directly from
32*5d9d9091SRichard Lowe * exec() upon invocation of a dynamically linked program specifying ld.so
33*5d9d9091SRichard Lowe * as its interpreter.
34*5d9d9091SRichard Lowe *
35*5d9d9091SRichard Lowe * On entry, the stack appears as:
36*5d9d9091SRichard Lowe *
37*5d9d9091SRichard Lowe *	!_______________________!  high addresses
38*5d9d9091SRichard Lowe *	!			!
39*5d9d9091SRichard Lowe *	!	Information	!
40*5d9d9091SRichard Lowe *	!	Block		!
41*5d9d9091SRichard Lowe *	!	(size varies)	!
42*5d9d9091SRichard Lowe *	!_______________________!
43*5d9d9091SRichard Lowe *	!	0 word		!
44*5d9d9091SRichard Lowe *	!_______________________!
45*5d9d9091SRichard Lowe *	!	Auxiliary	!
46*5d9d9091SRichard Lowe *	!	vector		!
47*5d9d9091SRichard Lowe *	!	2 word entries	!
48*5d9d9091SRichard Lowe *	!			!
49*5d9d9091SRichard Lowe *	!_______________________!
50*5d9d9091SRichard Lowe *	!	0 word		!
51*5d9d9091SRichard Lowe *	!_______________________!
52*5d9d9091SRichard Lowe *	!	Environment	!
53*5d9d9091SRichard Lowe *	!	pointers	!
54*5d9d9091SRichard Lowe *	!	...		!
55*5d9d9091SRichard Lowe *	!	(one word each)	!
56*5d9d9091SRichard Lowe *	!_______________________!
57*5d9d9091SRichard Lowe *	!	0 word		!
58*5d9d9091SRichard Lowe *	!_______________________!
59*5d9d9091SRichard Lowe *	!	Argument	! low addresses
60*5d9d9091SRichard Lowe *	!	pointers	!
61*5d9d9091SRichard Lowe *	!	Argc words	!
62*5d9d9091SRichard Lowe *	!_______________________!
63*5d9d9091SRichard Lowe *	!			!
64*5d9d9091SRichard Lowe *	!	Argc		!
65*5d9d9091SRichard Lowe *	!_______________________! <- %sp + 64
66*5d9d9091SRichard Lowe *	!			!
67*5d9d9091SRichard Lowe *	!   Window save area	!
68*5d9d9091SRichard Lowe *	!_______________________! <- %sp
69*5d9d9091SRichard Lowe */
70*5d9d9091SRichard Lowe
71*5d9d9091SRichard Lowe#if	defined(lint)
72*5d9d9091SRichard Lowe
73*5d9d9091SRichard Loweextern	unsigned long	_setup();
74*5d9d9091SRichard Loweextern	void		atexit_fini();
75*5d9d9091SRichard Lowe
76*5d9d9091SRichard Lowevoid
77*5d9d9091SRichard Lowemain()
78*5d9d9091SRichard Lowe{
79*5d9d9091SRichard Lowe	(void) _setup();
80*5d9d9091SRichard Lowe	atexit_fini();
81*5d9d9091SRichard Lowe}
82*5d9d9091SRichard Lowe
83*5d9d9091SRichard Lowe#else
84*5d9d9091SRichard Lowe
85*5d9d9091SRichard Lowe#include <sys/asm_linkage.h>
86*5d9d9091SRichard Lowe#include <sys/param.h>
87*5d9d9091SRichard Lowe#include <link.h>
88*5d9d9091SRichard Lowe
89*5d9d9091SRichard Lowe	.file	"boot.s"
90*5d9d9091SRichard Lowe	.seg	".text"
91*5d9d9091SRichard Lowe	.global	_rt_boot, _setup, atexit_fini
92*5d9d9091SRichard Lowe	.type	_rt_boot, #function
93*5d9d9091SRichard Lowe	.align	4
94*5d9d9091SRichard Lowe
95*5d9d9091SRichard Lowe! Entry vector
96*5d9d9091SRichard Lowe!	+0: normal start
97*5d9d9091SRichard Lowe!	+4: compatibility start, now an error
98*5d9d9091SRichard Lowe!	+8: alias start (frame exists)
99*5d9d9091SRichard Lowe
100*5d9d9091SRichard Lowe_rt_boot:
101*5d9d9091SRichard Lowe	ba,a	_elf_start
102*5d9d9091SRichard Lowe	ba,a	_aout_start
103*5d9d9091SRichard Lowe	ba,a	_alias_start
104*5d9d9091SRichard Lowe
105*5d9d9091SRichard Lowe! Start up routines -- the aout_start will have a pointer in %o0 that we'll
106*5d9d9091SRichard Lowe! want to save -- the elf can be zeroed.
107*5d9d9091SRichard Lowe
108*5d9d9091SRichard Lowe_elf_start:
109*5d9d9091SRichard Lowe	clr	%o0			! 0 in %o0 == ELF
110*5d9d9091SRichard Lowe_aout_start:				! (falls through)
111*5d9d9091SRichard Lowe
112*5d9d9091SRichard Lowe! Create a stack frame, perform PIC set up.  If we're a "normal" start, we have
113*5d9d9091SRichard Lowe! to determine a bunch of things from our "environment" and construct an ELF
114*5d9d9091SRichard Lowe! boot attribute value vector.  Otherwise, it's already been done and we can
115*5d9d9091SRichard Lowe! skip it.
116*5d9d9091SRichard Lowe
117*5d9d9091SRichard Lowe	save	%sp, -SA(MINFRAME + (EB_MAX * 8)), %sp
118*5d9d9091SRichard Lowe_alias_start:
119*5d9d9091SRichard Lowe1:					! PIC prologue
120*5d9d9091SRichard Lowe	call	2f
121*5d9d9091SRichard Lowe	sethi	%hi(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
122*5d9d9091SRichard Lowe2:
123*5d9d9091SRichard Lowe	or	%l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
124*5d9d9091SRichard Lowe
125*5d9d9091SRichard Lowe! If %i0 (was %o0) is non-zero, we're in compatibility and we can
126*5d9d9091SRichard Lowe! skip construction of the ELF boot attribute vector.
127*5d9d9091SRichard Lowe
128*5d9d9091SRichard Lowe	addcc	%i0, %g0, %o0		! set condition codes
129*5d9d9091SRichard Lowe	bne	1f			! if non-zero, skip setup
130*5d9d9091SRichard Lowe	add	%l7, %o7, %l7		! finish PIC prologue
131*5d9d9091SRichard Lowe
132*5d9d9091SRichard Lowe! %fp points to the root of our ELF bootstrap vector, use it to construct
133*5d9d9091SRichard Lowe! the vector and send it to _setup.
134*5d9d9091SRichard Lowe
135*5d9d9091SRichard Lowe	add	%sp, SA(MINFRAME), %o0	! &eb[0] == %sp + frame size
136*5d9d9091SRichard Lowe	set	EB_ARGV, %l0		! code for this entry
137*5d9d9091SRichard Lowe	st	%l0, [%o0]		!   store it
138*5d9d9091SRichard Lowe	add	%fp, 68, %l0		! argument vector is at %fp+68
139*5d9d9091SRichard Lowe	st	%l0, [%o0 + 4]		!   store that
140*5d9d9091SRichard Lowe	ld	[%fp + 64], %l1		! get argument count
141*5d9d9091SRichard Lowe	inc	%l1			! account for last element of 0
142*5d9d9091SRichard Lowe	sll	%l1, 2, %l1		! multiply by 4
143*5d9d9091SRichard Lowe	add	%l0, %l1, %l0		!   and get address of first env ptr
144*5d9d9091SRichard Lowe	st	%l0, [%o0 + 12]		! store it in the vector
145*5d9d9091SRichard Lowe	set	EB_ENVP, %l1		! code for environment base
146*5d9d9091SRichard Lowe	st	%l1, [%o0 + 8]		!   store it
147*5d9d9091SRichard Lowe	set	EB_AUXV, %l1		! get code for auxiliary vector
148*5d9d9091SRichard Lowe	st	%l1, [%o0 + 16]		!   store it
149*5d9d9091SRichard Lowe2:
150*5d9d9091SRichard Lowe	ld	[%l0], %l1		! get an entry
151*5d9d9091SRichard Lowe	tst	%l1			! are we at a "0" entry in environment?
152*5d9d9091SRichard Lowe	bne	2b			!   no, go back and look again
153*5d9d9091SRichard Lowe	add	%l0, 4, %l0		!	incrementing pointer in delay
154*5d9d9091SRichard Lowe	st	%l0, [%o0 + 20]		! store aux vector pointer
155*5d9d9091SRichard Lowe	set	EB_NULL, %l0		! set up for the last pointer
156*5d9d9091SRichard Lowe	st	%l0, [%o0 + 24]		!   and store it
157*5d9d9091SRichard Lowe
158*5d9d9091SRichard Lowe! Call _setup.  Two arguments, the ELF bootstrap vector and our (unrelocated)
159*5d9d9091SRichard Lowe! _DYNAMIC address.  The _DYNAMIC address is located in entry 0 of the GOT
160*5d9d9091SRichard Lowe
161*5d9d9091SRichard Lowe1:
162*5d9d9091SRichard Lowe	mov	%g0, %g2		! clear globals
163*5d9d9091SRichard Lowe	mov	%g0, %g3
164*5d9d9091SRichard Lowe	call	_setup			! call it
165*5d9d9091SRichard Lowe	ld	[%l7], %o1		! 2nd parameter
166*5d9d9091SRichard Lowe
167*5d9d9091SRichard Lowe! On return, give callee the exit function in %g1, and either jump to the
168*5d9d9091SRichard Lowe! target program (normal), or if return value of _setup is "0" we have
169*5d9d9091SRichard Lowe! to return to the compatibility bootstrap.  In either case, clear out
170*5d9d9091SRichard Lowe! reserved globals.
171*5d9d9091SRichard Lowe
172*5d9d9091SRichard Lowe	ld	[%l7 + atexit_fini], %g1! get function address
173*5d9d9091SRichard Lowe	restore	%o0, %g0, %l1		! release frame
174*5d9d9091SRichard Lowe	tst	%l1			! compatibility return?
175*5d9d9091SRichard Lowe	be	1f			! yes,
176*5d9d9091SRichard Lowe	mov	%g0, %g4		!   but clear one last global in delay
177*5d9d9091SRichard Lowe	jmpl	%l1, %g0		! call main program
178*5d9d9091SRichard Lowe	nop
179*5d9d9091SRichard Lowe1:
180*5d9d9091SRichard Lowe	retl				! compatibility return
181*5d9d9091SRichard Lowe	nop
182*5d9d9091SRichard Lowe
183*5d9d9091SRichard Lowe	.size	_rt_boot, . - _rt_boot
184*5d9d9091SRichard Lowe#endif
185