xref: /titanic_41/usr/src/cmd/sgs/rtld/sparc/boot.s (revision b02637af6dc592eb1f43cb4c74f06268648dbd2d)
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
5*b02637afSrie * Common Development and Distribution License (the "License").
6*b02637afSrie * 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 */
21*b02637afSrie
227c478bd9Sstevel@tonic-gate/*
237c478bd9Sstevel@tonic-gate *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate *
26*b02637afSrie * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
27*b02637afSrie * Use is subject to license terms.
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate/*
327c478bd9Sstevel@tonic-gate * Bootstrap routine for ld.so.  Control arrives here either directly from
337c478bd9Sstevel@tonic-gate * exec() upon invocation of a dynamically linked program specifying ld.so
347c478bd9Sstevel@tonic-gate * as its interpreter, or from the "a.out compatibility ld.so".  Entry
357c478bd9Sstevel@tonic-gate * vector at "_rt_boot" used to discriminate between the two.
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate * On entry, the stack appears as:
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate *	!_______________________!  high addresses
407c478bd9Sstevel@tonic-gate *	!			!
417c478bd9Sstevel@tonic-gate *	!	Information	!
427c478bd9Sstevel@tonic-gate *	!	Block		!
437c478bd9Sstevel@tonic-gate *	!	(size varies)	!
447c478bd9Sstevel@tonic-gate *	!_______________________!
457c478bd9Sstevel@tonic-gate *	!	0 word		!
467c478bd9Sstevel@tonic-gate *	!_______________________!
477c478bd9Sstevel@tonic-gate *	!	Auxiliary	!
487c478bd9Sstevel@tonic-gate *	!	vector		!
497c478bd9Sstevel@tonic-gate *	!	2 word entries	!
507c478bd9Sstevel@tonic-gate *	!			!
517c478bd9Sstevel@tonic-gate *	!_______________________!
527c478bd9Sstevel@tonic-gate *	!	0 word		!
537c478bd9Sstevel@tonic-gate *	!_______________________!
547c478bd9Sstevel@tonic-gate *	!	Environment	!
557c478bd9Sstevel@tonic-gate *	!	pointers	!
567c478bd9Sstevel@tonic-gate *	!	...		!
577c478bd9Sstevel@tonic-gate *	!	(one word each)	!
587c478bd9Sstevel@tonic-gate *	!_______________________!
597c478bd9Sstevel@tonic-gate *	!	0 word		!
607c478bd9Sstevel@tonic-gate *	!_______________________!
617c478bd9Sstevel@tonic-gate *	!	Argument	! low addresses
627c478bd9Sstevel@tonic-gate *	!	pointers	!
637c478bd9Sstevel@tonic-gate *	!	Argc words	!
647c478bd9Sstevel@tonic-gate *	!_______________________!
657c478bd9Sstevel@tonic-gate *	!			!
667c478bd9Sstevel@tonic-gate *	!	Argc		!
677c478bd9Sstevel@tonic-gate *	!_______________________! <- %sp + 64
687c478bd9Sstevel@tonic-gate *	!			!
697c478bd9Sstevel@tonic-gate *	!   Window save area	!
707c478bd9Sstevel@tonic-gate *	!_______________________! <- %sp
717c478bd9Sstevel@tonic-gate *
727c478bd9Sstevel@tonic-gate * In the case of being invoked from the a.out compatibility ld.so, the stack
737c478bd9Sstevel@tonic-gate * has the appearance above but also several frames pushed by the compatibility
747c478bd9Sstevel@tonic-gate * routine.  An "elf_boot" structure is available in %o1 on entry, which
757c478bd9Sstevel@tonic-gate * has been "pre-evaluated" to hold much of the information needed from the
767c478bd9Sstevel@tonic-gate * original stack frame -- we pass this directly into the main portion of the
777c478bd9Sstevel@tonic-gate * ld.so bootstrap.
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate#if	defined(lint)
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gateextern	unsigned long	_setup();
837c478bd9Sstevel@tonic-gateextern	void		atexit_fini();
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gatevoid
867c478bd9Sstevel@tonic-gatemain()
877c478bd9Sstevel@tonic-gate{
887c478bd9Sstevel@tonic-gate	(void) _setup();
897c478bd9Sstevel@tonic-gate	atexit_fini();
907c478bd9Sstevel@tonic-gate}
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate#else
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
957c478bd9Sstevel@tonic-gate#include <sys/param.h>
967c478bd9Sstevel@tonic-gate#include <link.h>
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate	.file	"boot.s"
997c478bd9Sstevel@tonic-gate	.seg	".text"
1007c478bd9Sstevel@tonic-gate	.global	_rt_boot, _setup, atexit_fini
1017c478bd9Sstevel@tonic-gate	.type	_rt_boot, #function
1027c478bd9Sstevel@tonic-gate	.align	4
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate! Entry vector
1057c478bd9Sstevel@tonic-gate!	+0: normal start
1067c478bd9Sstevel@tonic-gate!	+4: compatibility start
1077c478bd9Sstevel@tonic-gate!	+8: alias start (frame exists)
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate_rt_boot:
1107c478bd9Sstevel@tonic-gate	ba,a	_elf_start
1117c478bd9Sstevel@tonic-gate	ba,a	_aout_start
1127c478bd9Sstevel@tonic-gate	ba,a	_alias_start
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate! Start up routines -- the aout_start will have a pointer in %o0 that we'll
1157c478bd9Sstevel@tonic-gate! want to save -- the elf can be zeroed.
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate_elf_start:
1187c478bd9Sstevel@tonic-gate	clr	%o0			! 0 in %o0 == ELF
1197c478bd9Sstevel@tonic-gate_aout_start:				! (falls through)
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate! Create a stack frame, perform PIC set up.  If we're a "normal" start, we have
1227c478bd9Sstevel@tonic-gate! to determine a bunch of things from our "environment" and construct an ELF
1237c478bd9Sstevel@tonic-gate! boot attribute value vector.  Otherwise, it's already been done and we can
1247c478bd9Sstevel@tonic-gate! skip it.
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + (EB_MAX * 8)), %sp
1277c478bd9Sstevel@tonic-gate_alias_start:
1287c478bd9Sstevel@tonic-gate1:					! PIC prologue
1297c478bd9Sstevel@tonic-gate	call	2f
1307c478bd9Sstevel@tonic-gate	sethi	%hi(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
1317c478bd9Sstevel@tonic-gate2:
1327c478bd9Sstevel@tonic-gate	or	%l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate! If %i0 (was %o0) is non-zero, we're in compatibility and we can
1357c478bd9Sstevel@tonic-gate! skip construction of the ELF boot attribute vector.
1367c478bd9Sstevel@tonic-gate
1377c478bd9Sstevel@tonic-gate	addcc	%i0, %g0, %o0		! set condition codes
1387c478bd9Sstevel@tonic-gate	bne	1f			! if non-zero, skip setup
1397c478bd9Sstevel@tonic-gate	add	%l7, %o7, %l7		! finish PIC prologue
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate! %fp points to the root of our ELF bootstrap vector, use it to construct
1427c478bd9Sstevel@tonic-gate! the vector and send it to _setup.
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate	add	%sp, SA(MINFRAME), %o0	! &eb[0] == %sp + frame size
1457c478bd9Sstevel@tonic-gate	set	EB_ARGV, %l0		! code for this entry
1467c478bd9Sstevel@tonic-gate	st	%l0, [%o0]		!   store it
1477c478bd9Sstevel@tonic-gate	add	%fp, 68, %l0		! argument vector is at %fp+68
1487c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 4]		!   store that
1497c478bd9Sstevel@tonic-gate	ld	[%fp + 64], %l1		! get argument count
1507c478bd9Sstevel@tonic-gate	inc	%l1			! account for last element of 0
1517c478bd9Sstevel@tonic-gate	sll	%l1, 2, %l1		! multiply by 4
1527c478bd9Sstevel@tonic-gate	add	%l0, %l1, %l0		!   and get address of first env ptr
1537c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 12]		! store it in the vector
1547c478bd9Sstevel@tonic-gate	set	EB_ENVP, %l1		! code for environment base
1557c478bd9Sstevel@tonic-gate	st	%l1, [%o0 + 8]		!   store it
1567c478bd9Sstevel@tonic-gate	set	EB_AUXV, %l1		! get code for auxiliary vector
1577c478bd9Sstevel@tonic-gate	st	%l1, [%o0 + 16]		!   store it
1587c478bd9Sstevel@tonic-gate2:
1597c478bd9Sstevel@tonic-gate	ld	[%l0], %l1		! get an entry
1607c478bd9Sstevel@tonic-gate	tst	%l1			! are we at a "0" entry in environment?
1617c478bd9Sstevel@tonic-gate	bne	2b			!   no, go back and look again
1627c478bd9Sstevel@tonic-gate	add	%l0, 4, %l0		!	incrementing pointer in delay
1637c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 20]		! store aux vector pointer
1647c478bd9Sstevel@tonic-gate	set	EB_NULL, %l0		! set up for the last pointer
1657c478bd9Sstevel@tonic-gate	st	%l0, [%o0 + 24]		!   and store it
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate! Call _setup.  Two arguments, the ELF bootstrap vector and our (unrelocated)
1687c478bd9Sstevel@tonic-gate! _DYNAMIC address.  The _DYNAMIC address is located in entry 0 of the GOT
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate1:
1717c478bd9Sstevel@tonic-gate	mov	%g0, %g2		! clear globals
1727c478bd9Sstevel@tonic-gate	mov	%g0, %g3
1737c478bd9Sstevel@tonic-gate	call	_setup			! call it
1747c478bd9Sstevel@tonic-gate	ld	[%l7], %o1		! 2nd parameter
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate! On return, give callee the exit function in %g1, and either jump to the
1777c478bd9Sstevel@tonic-gate! target program (normal), or if return value of _setup is "0" we have
1787c478bd9Sstevel@tonic-gate! to return to the compatibility bootstrap.  In either case, clear out
1797c478bd9Sstevel@tonic-gate! reserved globals.
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate	ld	[%l7 + atexit_fini], %g1! get function address
1827c478bd9Sstevel@tonic-gate	restore	%o0, %g0, %l1		! release frame
1837c478bd9Sstevel@tonic-gate	tst	%l1			! compatibility return?
1847c478bd9Sstevel@tonic-gate	be	1f			! yes,
1857c478bd9Sstevel@tonic-gate	mov	%g0, %g4		!   but clear one last global in delay
1867c478bd9Sstevel@tonic-gate	jmpl	%l1, %g0		! call main program
1877c478bd9Sstevel@tonic-gate	nop
1887c478bd9Sstevel@tonic-gate1:
1897c478bd9Sstevel@tonic-gate	retl				! compatibility return
1907c478bd9Sstevel@tonic-gate	nop
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate	.size	_rt_boot, . - _rt_boot
1937c478bd9Sstevel@tonic-gate#endif
194