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 95 1: 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 146 1: 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 */ 163 1: 164 /* 165 * The stack needs to be 16-byte aligned with a 4-byte bias. See 166 * comment in lib/libc/i386/gen/makectxt.c. 167 * 168 * Note: If you change it, you need to change it in the following 169 * files as well: 170 * 171 * - lib/libc/i386/threads/machdep.c 172 * - lib/libc/i386/gen/makectxt.c 173 * - lib/common/i386/crti.s 174 */ 175 andl $-16,%esp /* make main() and exit() be called with */ 176 subl $4,%esp /* a properly aligned stack pointer */ 177 pushl %edx 178 leal 12(%ebp),%edx /* argv */ 179 movl %edx,___Argv 180 pushl %edx 181 pushl %eax /* argc */ 182 call __fpstart 183 call __fsr /* support for ftrap/fround/fprecision */ 184 call _init 185 call main /* main(argc,argv,envp) */ 186 movl %eax,(%esp) /* return value from main, for exit() */ 187 movl %eax,4(%esp) /* remember it for _exit(), below */ 188 call exit 189 movl 4(%esp),%eax /* if user redefined exit, call _exit */ 190 movl %eax,(%esp) 191 call _exit 192 hlt 193 .size _start, .-_start 194 195 #include "fsr.s" 196 197 /* 198 * The following is here in case any object module compiled with cc -p 199 * was linked into this module. 200 */ 201 .section .text 202 .align 4 203 .globl _mcount 204 .type _mcount,@function 205 _mcount: 206 ret 207 .size _mcount, .-_mcount 208 209 .section .data 210 211 .globl __longdouble_used 212 .type __longdouble_used,@object 213 .size __longdouble_used,4 214 .align 4 215 __longdouble_used: 216 .4byte 0x0