Home | History | Annotate | Download | only in amd64
      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 crt1.o module is provided as the bare minimum required to build a
     29  * 64-bit progile executable with gcc -pg.  It is installed in /usr/lib/amd64
     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,8
     58 	.align	8
     59 _environ:
     60 	.8byte	0x0
     61 
     62 	.globl	___Argv
     63 	.type	___Argv,@object
     64 	.size	___Argv,8
     65 	.align	8
     66 ___Argv:
     67 	.8byte	0x0
     68 
     69 	.section	.text
     70 	.align	8
     71 
     72 /*
     73  *   The SVR4/i386 ABI (pages 3-29) says that when the entry
     74  *   point runs registers' %rbp, %rsp, %rdx values are specified
     75  *   the following:
     76  *
     77  *	%rbp The content of this register is unspecified at
     78  *		process initialization time, but the user code should mark
     79  *		the deepest stack frame by setting the frame pointer to zero.
     80  *		No other frame's %ebp should have a zero value.
     81  *
     82  *	%rsp Performing its usual job, the stack pointer holds the address
     83  *	of the bottom of the stack, which is guaranteed to be
     84  *	quadword aligned.
     85  *
     86  *		The stack contains the arguments and environment:
     87  *        ...
     88  *        envp[0]		(16+(8*argc))(%rsp)
     89  *        NULL			(8+(8*argc))(%rsp)
     90  *        ...
     91  *        argv[0]		8(%rsp)
     92  *        argc			0(%rsp)
     93  *
     94  *	%rdx In a conforming program, this register contains a function
     95  *		pointer that the application should register with atexit(BA_OS).
     96  *		This function is used for shared object termination code
     97  *		[see Dynamic Linking in Chapter 5 of the System V ABI].
     98  *
     99  */
    100 
    101 	.type	_start,@function
    102 _start:
    103 /*
    104  * Allocate a NULL return address and a NULL previous %rbp as if
    105  * there was a genuine call to _start.
    106  */
    107 	pushq	$0
    108 	pushq	$0
    109 	movq	%rsp,%rbp		/* The first stack frame */
    110 
    111 /*
    112  * The stack now is
    113  *
    114  *        envp[0]		(32+(8*argc))(%rsp)      - (A)
    115  *        NULL			(24+(8*argc))(%rsp)
    116  *        ...
    117  *        argv[0]		24(%rbp)		 - (B)
    118  *        argc			16(%rbp)
    119  *	  0			8(%rbp)
    120  *	  0			0(%rbp)
    121  */
    122 
    123 /*
    124  * Check to see if there is an _mcleanup() function linked in, and if so,
    125  * register it with atexit() as the last thing to be run by exit().
    126  */
    127 	movq	%rdx,%r12		/* save rt_do_exit for later atexit */
    128 
    129 	movq	$_mcleanup,%rdi
    130 	testq	%rdi,%rdi
    131 	jz	1f
    132 	call	atexit
    133 1:
    134 
    135 	movq	$_DYNAMIC,%rax
    136 	testq	%rax,%rax
    137 	jz	1f
    138 	movq	%r12,%rdi		/* register rt_do_exit */
    139 	call	atexit
    140 1:
    141 
    142 	movq	$_fini,%rdi
    143 	call	atexit
    144 
    145 /* start profiling */
    146 	pushq	%rbp
    147 	movq	%rsp,%rbp
    148 	movq	$_start,%rdi
    149 	movq	$_etext,%rsi
    150 	call	monstartup
    151 	popq	%rbp
    152 
    153 /*
    154  * Calculate the location of the envp array by adding the size of
    155  * the argv array to the start of the argv array.
    156  */
    157 	movq	16(%rbp),%rax		/* argc */
    158 	movq	_environ, %rcx
    159 	testq	%rcx, %rcx		/* check if _environ==0 */
    160 	jne	1f
    161 	leaq	32(%rbp,%rax,8),%rcx	/* (A) */
    162 	movq	%rcx,_environ		/* copy to _environ */
    163 1:
    164 
    165 /*
    166  * Force stack alignment - below here there must have been an even
    167  * number of un-popped pushq instructions whenever a call is reached
    168  */
    169 	andq	$-16,%rsp
    170 	pushq	%rdx
    171 	leaq	24(%rbp),%rdx		/* argv (B) */
    172 	movq	%rdx,___Argv
    173 	pushq	%rcx
    174 	pushq	%rdx
    175 	pushq	%rax
    176 	call	__fpstart
    177 	call	_init
    178 	popq	%rdi
    179 	popq	%rsi
    180 	popq	%rdx
    181 	popq	%rcx
    182 	call	main			/* main(argc,argv,envp) */
    183 	pushq	%rax
    184 	pushq	%rax
    185 	movq	%rax,%rdi		/* and call exit */
    186 	call	exit
    187 	popq	%rdi
    188 	popq	%rdi
    189 	call	_exit		/* if user redefined exit, call _exit */
    190 	hlt
    191 	.size	_start, .-_start
    192