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