xref: /titanic_41/usr/src/lib/common/i386/crt1.s (revision a0bbbcfa4d3f0193d5e68171a110f3067bc582e3)
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 2009 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	.file	"crt1.s"
34
35	.globl	_start
36
37/* global entities defined elsewhere but used here */
38	.globl	main
39	.globl	__fpstart
40	.globl	exit
41	.globl	_exit
42	.weak	_DYNAMIC
43
44	.section	.data
45
46	.weak	environ
47	.set	environ,_environ
48	.globl	_environ
49	.type	_environ,@object
50	.size	_environ,4
51	.align	4
52_environ:
53	.4byte	0x0
54
55	.globl	__environ_lock
56	.type	__environ_lock,@object
57	.size	__environ_lock,24
58	.align	8
59__environ_lock:
60	.zero	24
61
62	.globl	___Argv
63	.type	___Argv,@object
64	.size	___Argv,4
65	.align	4
66___Argv:
67	.4byte	0x0
68
69	.section	.text
70	.align	4
71
72/*
73 * C language startup routine.
74 * Assume that exec code has cleared the direction flag in the TSS.
75 * Assume that %esp is set to the addr after the last word pushed.
76 * The stack contains (in order): argc, argv[],envp[],...
77 * Assume that all of the segment registers are initialized.
78 *
79 * Allocate a NULL return address and a NULL previous %ebp as if
80 * there was a genuine call to _start.
81 * sdb stack trace shows _start(argc,argv[0],argv[1],...,envp[0],...)
82 */
83	.type	_start,@function
84_start:
85	pushl	$0
86	pushl	$0
87	movl	%esp,%ebp		/* The first stack frame */
88
89	movl	$_DYNAMIC,%eax
90	testl	%eax,%eax
91	jz	1f
92	pushl	%edx			/* register rt_do_exit */
93	call	atexit
94	addl	$4,%esp
951:
96	pushl	$_fini
97	call	atexit
98	addl	$4,%esp
99
100/*
101 * The following code provides almost standard static destructor handling
102 * for systems that do not have the modified atexit processing in their
103 * system libraries.  It checks for the existence of the new routine
104 * "_get_exit_frame_monitor()", which is in libc.so when the new exit-handling
105 * code is there.  It then check for the existence of "__Crun::do_exit_code()"
106 * which will be in libCrun.so whenever the code was linked with the C++
107 * compiler.  If there is no enhanced atexit, and we do have do_exit_code,
108 * we register the latter with atexit.  There are 5 extra slots in
109 * atexit, so this will still be standard conforming.  Since the code
110 * is registered after the .fini section, it runs before the library
111 * cleanup code, leaving nothing for the calls to _do_exit_code_in_range
112 * to handle.
113 *
114 * Remove this code and the associated code in libCrun when the earliest
115 * system to be supported is Solaris 8.
116 */
117	.weak	_get_exit_frame_monitor
118	.weak	__1cG__CrunMdo_exit_code6F_v_
119
120	.section	.data
121	.align	4
122__get_exit_frame_monitor_ptr:
123	.4byte	_get_exit_frame_monitor
124	.type	__get_exit_frame_monitor_ptr,@object
125	.size	__get_exit_frame_monitor_ptr,4
126
127	.align	4
128__do_exit_code_ptr:
129	.4byte	__1cG__CrunMdo_exit_code6F_v_
130	.type	__do_exit_code_ptr,@object
131	.size	__do_exit_code_ptr,4
132
133	.section	.text
134
135	lea	__get_exit_frame_monitor_ptr, %eax
136	movl	(%eax), %eax
137	testl	%eax,%eax
138	jz	1f
139	lea	__do_exit_code_ptr, %eax
140	movl	(%eax), %eax
141	testl	%eax, %eax
142	jz	1f
143	pushl	%eax
144	call	atexit		/* atexit(__Crun::do_exit_code()) */
145	addl	$4,%esp
1461:
147
148/*
149 * End of destructor handling code
150 */
151
152/*
153 * Calculate the location of the envp array by adding the size of
154 * the argv array to the start of the argv array.
155 */
156
157	movl	8(%ebp),%eax		/* argc */
158	movl	_environ, %edx		/* fixed bug 4302802 */
159	testl	%edx, %edx		/* check if _enviorn==0 */
160	jne	1f			/* fixed bug 4203802 */
161	leal	16(%ebp,%eax,4),%edx	/* envp */
162	movl	%edx,_environ		/* copy to _environ */
1631:
164	andl	$-16,%esp	/* make main() and exit() be called with */
165	subl	$4,%esp		/* a 16-byte aligned stack pointer */
166	pushl	%edx
167	leal	12(%ebp),%edx	/* argv */
168	movl	%edx,___Argv
169	pushl	%edx
170	pushl	%eax		/* argc */
171	call	__fpstart
172	call	__fsr		/* support for ftrap/fround/fprecision  */
173	call	_init
174	call	main		/* main(argc,argv,envp) */
175	movl	%eax,(%esp)	/* return value from main, for exit() */
176	movl	%eax,4(%esp)	/* remember it for _exit(), below */
177	call	exit
178	movl	4(%esp),%eax	/* if user redefined exit, call _exit */
179	movl	%eax,(%esp)
180	call	_exit
181	hlt
182	.size	_start, .-_start
183
184#include "fsr.s"
185
186/*
187 * The following is here in case any object module compiled with cc -p
188 *	was linked into this module.
189 */
190	.section	.text
191	.align	4
192	.globl	_mcount
193	.type	_mcount,@function
194_mcount:
195	ret
196	.size	_mcount, .-_mcount
197
198	.section	.data
199
200	.globl	__longdouble_used
201	.type	__longdouble_used,@object
202	.size	__longdouble_used,4
203	.align	4
204__longdouble_used:
205	.4byte	0x0
206