xref: /titanic_50/usr/src/cmd/sgs/rtld/i386/boot.s (revision 7a35e51d2464eff549397fe9f5a1092acd55b532)
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
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate/*
237c478bd9Sstevel@tonic-gate *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate *
267c478bd9Sstevel@tonic-gate *
277c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
287c478bd9Sstevel@tonic-gate * Use is subject to license terms.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate/*
327c478bd9Sstevel@tonic-gate * Bootstrap routine for run-time linker.
337c478bd9Sstevel@tonic-gate * We get control from exec which has loaded our text and
347c478bd9Sstevel@tonic-gate * data into the process' address space and created the process
357c478bd9Sstevel@tonic-gate * stack.
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate * On entry, the process stack looks like this:
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate *	#			# <- %esp
407c478bd9Sstevel@tonic-gate *	#_______________________#  high addresses
417c478bd9Sstevel@tonic-gate *	#	strings		#
427c478bd9Sstevel@tonic-gate *	#_______________________#
437c478bd9Sstevel@tonic-gate *	#	0 word		#
447c478bd9Sstevel@tonic-gate *	#_______________________#
457c478bd9Sstevel@tonic-gate *	#	Auxiliary	#
467c478bd9Sstevel@tonic-gate *	#	entries		#
477c478bd9Sstevel@tonic-gate *	#	...		#
487c478bd9Sstevel@tonic-gate *	#	(size varies)	#
497c478bd9Sstevel@tonic-gate *	#_______________________#
507c478bd9Sstevel@tonic-gate *	#	0 word		#
517c478bd9Sstevel@tonic-gate *	#_______________________#
527c478bd9Sstevel@tonic-gate *	#	Environment	#
537c478bd9Sstevel@tonic-gate *	#	pointers	#
547c478bd9Sstevel@tonic-gate *	#	...		#
557c478bd9Sstevel@tonic-gate *	#	(one word each)	#
567c478bd9Sstevel@tonic-gate *	#_______________________#
577c478bd9Sstevel@tonic-gate *	#	0 word		#
587c478bd9Sstevel@tonic-gate *	#_______________________#
597c478bd9Sstevel@tonic-gate *	#	Argument	# low addresses
607c478bd9Sstevel@tonic-gate *	#	pointers	#
617c478bd9Sstevel@tonic-gate *	#	Argc words	#
627c478bd9Sstevel@tonic-gate *	#_______________________#
637c478bd9Sstevel@tonic-gate *	#	argc		#
647c478bd9Sstevel@tonic-gate *	#_______________________# <- %ebp
657c478bd9Sstevel@tonic-gate *
667c478bd9Sstevel@tonic-gate *
677c478bd9Sstevel@tonic-gate * We must calculate the address at which ld.so was loaded,
687c478bd9Sstevel@tonic-gate * find the addr of the dynamic section of ld.so, of argv[0], and  of
697c478bd9Sstevel@tonic-gate * the process' environment pointers - and pass the thing to _setup
707c478bd9Sstevel@tonic-gate * to handle.  We then call _rtld - on return we jump to the entry
717c478bd9Sstevel@tonic-gate * point for the a.out.
727c478bd9Sstevel@tonic-gate */
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate#if	defined(lint)
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gateextern	unsigned long	_setup();
777c478bd9Sstevel@tonic-gateextern	void		atexit_fini();
787c478bd9Sstevel@tonic-gatevoid
797c478bd9Sstevel@tonic-gatemain()
807c478bd9Sstevel@tonic-gate{
817c478bd9Sstevel@tonic-gate	(void) _setup();
827c478bd9Sstevel@tonic-gate	atexit_fini();
837c478bd9Sstevel@tonic-gate}
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate#else
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate#include	<link.h>
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate	.file	"boot.s"
907c478bd9Sstevel@tonic-gate	.text
917c478bd9Sstevel@tonic-gate	.globl	_rt_boot
927c478bd9Sstevel@tonic-gate	.globl	_setup
937c478bd9Sstevel@tonic-gate	.globl	_GLOBAL_OFFSET_TABLE_
947c478bd9Sstevel@tonic-gate	.type	_rt_boot,@function
957c478bd9Sstevel@tonic-gate	.align	4
967c478bd9Sstevel@tonic-gate
97*7a35e51dSRichard Lowe	/ init is called from the _init symbol in the CRT, however .init_array
98*7a35e51dSRichard Lowe	/ are called "naturally" from call_init.  Because of that, we need the
99*7a35e51dSRichard Lowe	/ stack aligned here so that initializers called via _array sections may
100*7a35e51dSRichard Lowe	/ safely use SIMD instructions.
1017c478bd9Sstevel@tonic-gate_rt_alias:
1027c478bd9Sstevel@tonic-gate	jmp	.get_ip			/ in case we were invoked from libc.so
1037c478bd9Sstevel@tonic-gate_rt_boot:
1047c478bd9Sstevel@tonic-gate	movl	%esp,%ebp		/ save for referencing args
1057c478bd9Sstevel@tonic-gate	subl	$EB_MAX_SIZE32,%esp	/ make room for a max sized boot vector
106*7a35e51dSRichard Lowe	andl	$-16,%esp
107*7a35e51dSRichard Lowe	subl	$8,%esp
1087c478bd9Sstevel@tonic-gate	movl	%esp,%esi		/ use esi as a pointer to &eb[0]
1097c478bd9Sstevel@tonic-gate	movl	$EB_ARGV,0(%esi)	/ set up tag for argv
1107c478bd9Sstevel@tonic-gate	leal	4(%ebp),%eax		/ get address of argv
1117c478bd9Sstevel@tonic-gate	movl	%eax,4(%esi)		/ put after tag
1127c478bd9Sstevel@tonic-gate	movl	$EB_ENVP,8(%esi)	/ set up tag for envp
1137c478bd9Sstevel@tonic-gate	movl	(%ebp),%eax		/ get # of args
1147c478bd9Sstevel@tonic-gate	addl	$2,%eax			/ one for the zero & one for argc
1157c478bd9Sstevel@tonic-gate	leal	(%ebp,%eax,4),%edi	/ now points past args & @ envp
1167c478bd9Sstevel@tonic-gate	movl	%edi,12(%esi)		/ set envp
1177c478bd9Sstevel@tonic-gate.L0:	addl	$4,%edi			/ next
1187c478bd9Sstevel@tonic-gate	cmpl	$0,-4(%edi)		/ search for 0 at end of env
1197c478bd9Sstevel@tonic-gate	jne	.L0
1207c478bd9Sstevel@tonic-gate	movl	$EB_AUXV,16(%esi)	/ set up tag for auxv
1217c478bd9Sstevel@tonic-gate	movl	%edi,20(%esi)		/ point to auxv
1227c478bd9Sstevel@tonic-gate	movl	$EB_NULL,24(%esi)	/ set up NULL tag
1237c478bd9Sstevel@tonic-gate.get_ip:
1247c478bd9Sstevel@tonic-gate	call	.L1			/ only way to get IP into a register
1257c478bd9Sstevel@tonic-gate.L1:
1267c478bd9Sstevel@tonic-gate	popl	%ebx			/ pop the IP we just "pushed"
1277c478bd9Sstevel@tonic-gate	addl	$_GLOBAL_OFFSET_TABLE_+[.-.L1],%ebx
1287c478bd9Sstevel@tonic-gate	pushl	(%ebx)			/ address of dynamic structure
1297c478bd9Sstevel@tonic-gate	pushl	%esi			/ push &eb[0]
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate	call	_setup@PLT		/ _setup(&eb[0], _DYNAMIC)
1327c478bd9Sstevel@tonic-gate	movl	%ebp,%esp		/ release stack frame
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate	movl	atexit_fini@GOT(%ebx), %edx
1357c478bd9Sstevel@tonic-gate	jmp	*%eax 			/ transfer control to a.out
1367c478bd9Sstevel@tonic-gate	.size	_rt_boot,.-_rt_boot
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate#endif
139