xref: /titanic_41/usr/src/lib/common/i386/crt1.s (revision 4470e6878e514c52138797efb506203d656b695f)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * This crt1.o module is provided as the bare minimum required to build
29 * a 32-bit executable with gcc.  It is installed in /usr/lib
30 * where it will be picked up by gcc, along with crti.o and crtn.o
31 */
32
33	.ident	"%Z%%M%	%I%	%E% SMI"
34
35	.file	"crt1.s"
36
37	.globl	_start
38
39/* global entities defined elsewhere but used here */
40	.globl	main
41	.globl	__fpstart
42	.globl	exit
43	.globl	_exit
44	.weak	_DYNAMIC
45
46	.section	.data
47
48	.weak	environ
49	.set	environ,_environ
50	.globl	_environ
51	.type	_environ,@object
52	.size	_environ,4
53	.align	4
54_environ:
55	.4byte	0x0
56
57	.globl	__environ_lock
58	.type	__environ_lock,@object
59	.size	__environ_lock,24
60	.align	4
61__environ_lock:
62	.zero	24
63
64	.globl	___Argv
65	.type	___Argv,@object
66	.size	___Argv,4
67	.align	4
68___Argv:
69	.4byte	0x0
70
71	.section	.text
72	.align	4
73
74/*
75 * C language startup routine.
76 * Assume that exec code has cleared the direction flag in the TSS.
77 * Assume that %esp is set to the addr after the last word pushed.
78 * The stack contains (in order): argc, argv[],envp[],...
79 * Assume that all of the segment registers are initialized.
80 *
81 * Allocate a NULL return address and a NULL previous %ebp as if
82 * there was a genuine call to _start.
83 * sdb stack trace shows _start(argc,argv[0],argv[1],...,envp[0],...)
84 */
85	.type	_start,@function
86_start:
87	pushl	$0
88	pushl	$0
89	movl	%esp,%ebp		/* The first stack frame */
90
91	movl	$_DYNAMIC,%eax
92	testl	%eax,%eax
93	jz	1f
94	pushl	%edx			/* register rt_do_exit */
95	call	atexit
96	addl	$4,%esp
971:
98	pushl	$_fini
99	call	atexit
100	addl	$4,%esp
101
102/*
103 * The following code provides almost standard static destructor handling
104 * for systems that do not have the modified atexit processing in their
105 * system libraries.  It checks for the existence of the new routine
106 * "_get_exit_frame_monitor()", which is in libc.so when the new exit-handling
107 * code is there.  It then check for the existence of "__Crun::do_exit_code()"
108 * which will be in libCrun.so whenever the code was linked with the C++
109 * compiler.  If there is no enhanced atexit, and we do have do_exit_code,
110 * we register the latter with atexit.  There are 5 extra slots in
111 * atexit, so this will still be standard conforming.  Since the code
112 * is registered after the .fini section, it runs before the library
113 * cleanup code, leaving nothing for the calls to _do_exit_code_in_range
114 * to handle.
115 *
116 * Remove this code and the associated code in libCrun when the earliest
117 * system to be supported is Solaris 8.
118 */
119	.weak	_get_exit_frame_monitor
120	.weak	__1cG__CrunMdo_exit_code6F_v_
121
122	.section	.data
123	.align	4
124__get_exit_frame_monitor_ptr:
125	.4byte	_get_exit_frame_monitor
126	.type	__get_exit_frame_monitor_ptr,@object
127	.size	__get_exit_frame_monitor_ptr,4
128
129	.align	4
130__do_exit_code_ptr:
131	.4byte	__1cG__CrunMdo_exit_code6F_v_
132	.type	__do_exit_code_ptr,@object
133	.size	__do_exit_code_ptr,4
134
135	.section	.text
136
137	lea	__get_exit_frame_monitor_ptr, %eax
138	movl	(%eax), %eax
139	testl	%eax,%eax
140	jz	1f
141	lea	__do_exit_code_ptr, %eax
142	movl	(%eax), %eax
143	testl	%eax, %eax
144	jz	1f
145	pushl	%eax
146	call	atexit		/* atexit(__Crun::do_exit_code()) */
147	addl	$4,%esp
1481:
149
150/*
151 * End of destructor handling code
152 */
153
154/*
155 * Calculate the location of the envp array by adding the size of
156 * the argv array to the start of the argv array.
157 */
158
159	movl	8(%ebp),%eax		/* argc */
160	movl	_environ, %edx		/* fixed bug 4302802 */
161	testl	%edx, %edx		/* check if _enviorn==0 */
162	jne	1f			/* fixed bug 4203802 */
163	leal	16(%ebp,%eax,4),%edx	/* envp */
164	movl	%edx,_environ		/* copy to _environ */
1651:
166	andl	$-16,%esp
167	pushl	%edx
168	leal	12(%ebp),%edx	/* argv */
169	movl	%edx,___Argv
170	pushl	%edx
171	pushl	%eax		/* argc */
172	call	__fpstart
173	call	__fsr		/* support for ftrap/fround/fprecision  */
174	call	_init
175	call	main		/* main(argc,argv,envp) */
176	addl	$12,%esp
177	pushl	%eax		/* return value from main */
178	pushl	%eax		/* push it again (for _exit(), below) */
179	call	exit
180	addl	$4,%esp
181	call	_exit		/* if user redefined exit, call _exit */
182	addl	$4,%esp
183	hlt
184	.size	_start, .-_start
185
186#include "fsr.s"
187
188/*
189 * The following is here in case any object module compiled with cc -p
190 *	was linked into this module.
191 */
192	.section	.text
193	.align	4
194	.globl	_mcount
195	.type	_mcount,@function
196_mcount:
197	ret
198	.size	_mcount, .-_mcount
199
200	.section	.data
201
202	.globl	__longdouble_used
203	.type	__longdouble_used,@object
204	.size	__longdouble_used,4
205	.align	4
206__longdouble_used:
207	.4byte	0x0
208