8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / common / i386 / gcrt1.s
blob71f807397a959551b004abe274ee4d27f206bd3f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * This gcrt1.o module is provided as the bare minimum required to build a
29 * 32-bit profile executable with gcc -pg. It is installed in /usr/lib
30 * where it will be picked up by gcc, along with crti.o and crtn.o
33 .ident "%Z%%M% %I% %E% SMI"
35 .file "gcrt1.s"
37 .globl _start
38 .globl _etext
40 /* global entities defined elsewhere but used here */
41 .globl main
42 .globl __fpstart
43 .globl _init
44 .globl _fini
45 .globl exit
46 .globl _exit
47 .globl monstartup
48 .weak _mcleanup
49 .weak _DYNAMIC
51 .section .data
53 .weak environ
54 .set environ,_environ
55 .globl _environ
56 .type _environ,@object
57 .size _environ,4
58 .align 4
59 _environ:
60 .4byte 0x0
62 .globl ___Argv
63 .type ___Argv,@object
64 .size ___Argv,4
65 .align 4
66 ___Argv:
67 .4byte 0x0
69 .section .text
70 .align 4
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.
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],...)
83 .type _start,@function
84 _start:
85 pushl $0
86 pushl $0
87 movl %esp,%ebp /* The first stack frame */
90 * Check to see if there is an _mcleanup() function linked in, and if so,
91 * register it with atexit() as the last thing to be run by exit().
93 pushl %edx /* save rt_do_exit for later atexit */
95 movl $_mcleanup,%eax
96 testl %eax,%eax
97 jz 1f
98 pushl %eax
99 call atexit
100 addl $4,%esp
103 movl $_DYNAMIC,%eax
104 testl %eax,%eax
105 jz 1f
106 call atexit /* register rt_do_exit */
108 addl $4,%esp
110 pushl $_fini
111 call atexit
112 addl $4,%esp
114 /* start profiling */
115 pushl %ebp
116 movl %esp,%ebp
117 pushl $_etext
118 pushl $_start
119 call monstartup
120 addl $8,%esp
121 popl %ebp
124 * The following code provides almost standard static destructor handling
125 * for systems that do not have the modified atexit processing in their
126 * system libraries. It checks for the existence of the new routine
127 * "_get_exit_frame_monitor()", which is in libc.so when the new exit-handling
128 * code is there. It then check for the existence of "__Crun::do_exit_code()"
129 * which will be in libCrun.so whenever the code was linked with the C++
130 * compiler. If there is no enhanced atexit, and we do have do_exit_code,
131 * we register the latter with atexit. There are 5 extra slots in
132 * atexit, so this will still be standard conforming. Since the code
133 * is registered after the .fini section, it runs before the library
134 * cleanup code, leaving nothing for the calls to _do_exit_code_in_range
135 * to handle.
137 * Remove this code and the associated code in libCrun when the earliest
138 * system to be supported is Solaris 8.
140 .weak _get_exit_frame_monitor
141 .weak __1cG__CrunMdo_exit_code6F_v_
143 .section .data
144 .align 4
145 __get_exit_frame_monitor_ptr:
146 .4byte _get_exit_frame_monitor
147 .type __get_exit_frame_monitor_ptr,@object
148 .size __get_exit_frame_monitor_ptr,4
150 .align 4
151 __do_exit_code_ptr:
152 .4byte __1cG__CrunMdo_exit_code6F_v_
153 .type __do_exit_code_ptr,@object
154 .size __do_exit_code_ptr,4
156 .section .text
158 lea __get_exit_frame_monitor_ptr, %eax
159 movl (%eax), %eax
160 testl %eax,%eax
161 jz 1f
162 lea __do_exit_code_ptr, %eax
163 movl (%eax), %eax
164 testl %eax, %eax
165 jz 1f
166 pushl %eax
167 call atexit /* atexit(__Crun::do_exit_code()) */
168 addl $4,%esp
172 * End of destructor handling code
176 * Calculate the location of the envp array by adding the size of
177 * the argv array to the start of the argv array.
180 movl 8(%ebp),%eax /* argc */
181 movl _environ, %edx /* fixed bug 4302802 */
182 testl %edx, %edx /* check if _enviorn==0 */
183 jne 1f /* fixed bug 4203802 */
184 leal 16(%ebp,%eax,4),%edx /* envp */
185 movl %edx,_environ /* copy to _environ */
187 andl $-16,%esp /* align the stack */
188 subl $4,%esp
190 pushl %edx
191 leal 12(%ebp),%edx /* argv */
192 movl %edx,___Argv
193 pushl %edx
194 pushl %eax /* argc */
195 call __fpstart
196 call _init
197 call main /* main(argc,argv,envp) */
198 addl $12,%esp
199 pushl %eax /* return value from main */
200 pushl %eax /* push it again (for _exit(), below) */
201 call exit
202 addl $4,%esp
203 call _exit /* if user redefined exit, call _exit */
204 addl $4,%esp
206 .size _start, .-_start