xref: /titanic_50/usr/src/cmd/sgs/rtld/sparcv9/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 directly from
337c478bd9Sstevel@tonic-gate * exec() upon invocation of a dynamically linked program specifying ld.so
347c478bd9Sstevel@tonic-gate * as its interpreter.
357c478bd9Sstevel@tonic-gate *
367c478bd9Sstevel@tonic-gate * On entry, the stack appears as:
377c478bd9Sstevel@tonic-gate *
387c478bd9Sstevel@tonic-gate *	!_______________________!  high addresses
397c478bd9Sstevel@tonic-gate *	!	0 word		!
407c478bd9Sstevel@tonic-gate *	!_______________________!
417c478bd9Sstevel@tonic-gate *	!			!
427c478bd9Sstevel@tonic-gate *	!	Information	!
437c478bd9Sstevel@tonic-gate *	!	Block		!
447c478bd9Sstevel@tonic-gate *	!	(size varies)	!
457c478bd9Sstevel@tonic-gate *	!_______________________!
467c478bd9Sstevel@tonic-gate *	!	Auxiliary	!
477c478bd9Sstevel@tonic-gate *	!	vector		!
487c478bd9Sstevel@tonic-gate *	!	2 word entries	!
497c478bd9Sstevel@tonic-gate *	!			!
507c478bd9Sstevel@tonic-gate *	!_______________________!
517c478bd9Sstevel@tonic-gate *	!	0 word		!
527c478bd9Sstevel@tonic-gate *	!_______________________!
537c478bd9Sstevel@tonic-gate *	!	Environment	!
547c478bd9Sstevel@tonic-gate *	!	pointers	!
557c478bd9Sstevel@tonic-gate *	!	...		!
567c478bd9Sstevel@tonic-gate *	!	(one word each)	!
577c478bd9Sstevel@tonic-gate *	!_______________________!
587c478bd9Sstevel@tonic-gate *	!	0 word		!
597c478bd9Sstevel@tonic-gate *	!_______________________!
607c478bd9Sstevel@tonic-gate *	!	Argument	! low addresses
617c478bd9Sstevel@tonic-gate *	!	pointers	!
627c478bd9Sstevel@tonic-gate *	!	Argc words	!
637c478bd9Sstevel@tonic-gate *	!_______________________!
647c478bd9Sstevel@tonic-gate *	!			!
657c478bd9Sstevel@tonic-gate *	!	Argc		!
667c478bd9Sstevel@tonic-gate *	!_______________________! <- %sp + STACK_BIAS + WINDOWSIZE
677c478bd9Sstevel@tonic-gate *	!			!
687c478bd9Sstevel@tonic-gate *	!   Window save area	!
697c478bd9Sstevel@tonic-gate *	!_______________________! <- %sp + STACK_BIAS
707c478bd9Sstevel@tonic-gate */
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate#if	defined(lint)
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gateextern	unsigned long	_setup();
757c478bd9Sstevel@tonic-gateextern	void		atexit_fini();
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gatevoid
787c478bd9Sstevel@tonic-gatemain()
797c478bd9Sstevel@tonic-gate{
807c478bd9Sstevel@tonic-gate	(void) _setup();
817c478bd9Sstevel@tonic-gate	atexit_fini();
827c478bd9Sstevel@tonic-gate}
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate#else
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
877c478bd9Sstevel@tonic-gate#include <sys/param.h>
887c478bd9Sstevel@tonic-gate#include <link.h>
897c478bd9Sstevel@tonic-gate
90*b02637afSrie	.file	"boot.s"
917c478bd9Sstevel@tonic-gate	.seg	".text"
927c478bd9Sstevel@tonic-gate	.global	_rt_boot, _setup, atexit_fini
937c478bd9Sstevel@tonic-gate	.type	_rt_boot, #function
947c478bd9Sstevel@tonic-gate	.align	4
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate! Entry vector
977c478bd9Sstevel@tonic-gate!	+0: normal start
987c478bd9Sstevel@tonic-gate!	+4: normal start
997c478bd9Sstevel@tonic-gate!	+8: alias start (frame exists)		XX64 what's this for?
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate_rt_boot:
1027c478bd9Sstevel@tonic-gate	nop
1037c478bd9Sstevel@tonic-gate	ba,a	_elf_start
1047c478bd9Sstevel@tonic-gate	ba,a	_alias_start
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate! Start up routines
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate_elf_start:
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate! Create a stack frame, perform PIC set up.  We have
1117c478bd9Sstevel@tonic-gate! to determine a bunch of things from our "environment" and
1127c478bd9Sstevel@tonic-gate! construct an Elf64_Boot attribute value vector.
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME + (EB_MAX * 16)), %sp
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate_alias_start:
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate1:					! PIC prologue
1197c478bd9Sstevel@tonic-gate	call	2f
1207c478bd9Sstevel@tonic-gate	sethi	%hh(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1
1217c478bd9Sstevel@tonic-gate2:	or	%g1, %hm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %g1
1227c478bd9Sstevel@tonic-gate	sllx	%g1, 32, %g5
1237c478bd9Sstevel@tonic-gate	sethi	%lm(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
1247c478bd9Sstevel@tonic-gate	or	%l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
1257c478bd9Sstevel@tonic-gate	or	%g5, %l7, %l7
1267c478bd9Sstevel@tonic-gate	add	%l7, %o7, %l7		! finish PIC prologue
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate! %fp points to the root of our ELF bootstrap vector, use it to construct
1297c478bd9Sstevel@tonic-gate! the vector and send it to _setup.
1307c478bd9Sstevel@tonic-gate!
1317c478bd9Sstevel@tonic-gate! The resulting Elf64_Boot vector looks like this:
1327c478bd9Sstevel@tonic-gate!
1337c478bd9Sstevel@tonic-gate!	Offset		Contents
1347c478bd9Sstevel@tonic-gate!	+0x0		EB_ARGV
1357c478bd9Sstevel@tonic-gate!	+0x8		argv[]
1367c478bd9Sstevel@tonic-gate!	+0x10		EB_ENVP
1377c478bd9Sstevel@tonic-gate! 	+0x18		envp[]
1387c478bd9Sstevel@tonic-gate!	+0x20		EB_AUXV
1397c478bd9Sstevel@tonic-gate!	+0x28		auxv[]
1407c478bd9Sstevel@tonic-gate!	+0x30		EB_NULL
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate	add	%sp, STACK_BIAS + SA(MINFRAME), %o0
1437c478bd9Sstevel@tonic-gate					! &eb[0] == %sp + frame size
1447c478bd9Sstevel@tonic-gate	mov	EB_ARGV, %l0		! code for this entry
1457c478bd9Sstevel@tonic-gate	stx	%l0, [%o0]		!   store it
1467c478bd9Sstevel@tonic-gate	add	%fp, WINDOWSIZE + 8 + STACK_BIAS, %l0
1477c478bd9Sstevel@tonic-gate					! argument vector
1487c478bd9Sstevel@tonic-gate	stx	%l0, [%o0 + 0x8]	!   store that
1497c478bd9Sstevel@tonic-gate	ldx	[%fp + WINDOWSIZE + STACK_BIAS], %l1
1507c478bd9Sstevel@tonic-gate					! get argument count (argc)
1517c478bd9Sstevel@tonic-gate	inc	%l1			! account for last element of 0
1527c478bd9Sstevel@tonic-gate	sllx	%l1, 3, %l1		! multiply by 8
1537c478bd9Sstevel@tonic-gate	add	%l0, %l1, %l0		!   and get address of first env ptr
1547c478bd9Sstevel@tonic-gate	stx	%l0, [%o0 + 0x18]	! store it in the vector
1557c478bd9Sstevel@tonic-gate	mov	EB_ENVP, %l1		! code for environment base
1567c478bd9Sstevel@tonic-gate	stx	%l1, [%o0 + 0x10]	!   store it
1577c478bd9Sstevel@tonic-gate	mov	EB_AUXV, %l1		! get code for auxiliary vector
1587c478bd9Sstevel@tonic-gate	stx	%l1, [%o0 + 0x20]	!   store it
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate3:	ldx	[%l0], %l1		! get an entry
1617c478bd9Sstevel@tonic-gate	brnz,pt	%l1, 3b			! if not at end, go back and look again
1627c478bd9Sstevel@tonic-gate	add	%l0, 8, %l0		!	incrementing pointer in delay
1637c478bd9Sstevel@tonic-gate	stx	%l0, [%o0 + 0x28]	! store aux vector pointer
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate	mov	EB_NULL, %l0		! set up for the last pointer
1667c478bd9Sstevel@tonic-gate	stx	%l0, [%o0 + 0x30]	!   and store it
1677c478bd9Sstevel@tonic-gate	mov	%g0, %g2		! clear globals
1687c478bd9Sstevel@tonic-gate	mov	%g0, %g3
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate! Call _setup.  Two arguments, the ELF bootstrap vector and our (unrelocated)
1717c478bd9Sstevel@tonic-gate! _DYNAMIC address.  The _DYNAMIC address is located in entry 0 of the GOT
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate	call	_setup			! call it
1757c478bd9Sstevel@tonic-gate	ldx	[%l7], %o1
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate! On return, give callee the exit function in %g1, and jump to the
1787c478bd9Sstevel@tonic-gate! target program, clearing out the reserved globals as we go.
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate	ldx	[%l7 + atexit_fini], %g1! get function address
1817c478bd9Sstevel@tonic-gate	restore	%o0, %g0, %l1		! release frame
1827c478bd9Sstevel@tonic-gate	jmpl	%l1, %g0		! call main program
1837c478bd9Sstevel@tonic-gate	mov	%g0, %g4		!   clear one last global in delay
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate	.size	_rt_boot, . - _rt_boot
1867c478bd9Sstevel@tonic-gate#endif
187