Home | History | Annotate | Download | only in i386
      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, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      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.
     13  *
     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]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     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
     31  */
     32 
     33 	.ident	"%Z%%M%	%I%	%E% SMI"
     34 
     35 	.file	"gcrt1.s"
     36 
     37 	.globl	_start
     38 	.globl	_etext
     39 
     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
     50 
     51 	.section	.data
     52 
     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
     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 /*
     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().
     92  */
     93 	pushl	%edx			/* save rt_do_exit for later atexit */
     94 
     95 	movl	$_mcleanup,%eax
     96 	testl	%eax,%eax
     97 	jz	1f
     98 	pushl	%eax
     99 	call	atexit
    100 	addl	$4,%esp
    101 1:
    102 
    103 	movl	$_DYNAMIC,%eax
    104 	testl	%eax,%eax
    105 	jz	1f
    106 	call	atexit			/* register rt_do_exit */
    107 1:
    108 	addl	$4,%esp
    109 
    110 	pushl	$_fini
    111 	call	atexit
    112 	addl	$4,%esp
    113 
    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
    122 
    123 /*
    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.
    136  *
    137  * Remove this code and the associated code in libCrun when the earliest
    138  * system to be supported is Solaris 8.
    139  */
    140 	.weak	_get_exit_frame_monitor
    141 	.weak	__1cG__CrunMdo_exit_code6F_v_
    142 
    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
    149 
    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
    155 
    156 	.section	.text
    157 
    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
    169 1:
    170 
    171 /*
    172  * End of destructor handling code
    173  */
    174 
    175 /*
    176  * Calculate the location of the envp array by adding the size of
    177  * the argv array to the start of the argv array.
    178  */
    179 
    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 */
    186 1:
    187 	andl	$-16,%esp	/* align the stack */
    188 	subl	$4,%esp
    189 
    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
    205 	hlt
    206 	.size	_start, .-_start
    207