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 951: 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 1461: 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 */ 1631: 164 andl $-16,%esp /* make main() and exit() be called with */ 165 subl $4,%esp /* a 16-byte aligned stack pointer */ 166 pushl %edx 167 leal 12(%ebp),%edx /* argv */ 168 movl %edx,___Argv 169 pushl %edx 170 pushl %eax /* argc */ 171 call __fpstart 172 call __fsr /* support for ftrap/fround/fprecision */ 173 call _init 174 call main /* main(argc,argv,envp) */ 175 movl %eax,(%esp) /* return value from main, for exit() */ 176 movl %eax,4(%esp) /* remember it for _exit(), below */ 177 call exit 178 movl 4(%esp),%eax /* if user redefined exit, call _exit */ 179 movl %eax,(%esp) 180 call _exit 181 hlt 182 .size _start, .-_start 183 184#include "fsr.s" 185 186/* 187 * The following is here in case any object module compiled with cc -p 188 * was linked into this module. 189 */ 190 .section .text 191 .align 4 192 .globl _mcount 193 .type _mcount,@function 194_mcount: 195 ret 196 .size _mcount, .-_mcount 197 198 .section .data 199 200 .globl __longdouble_used 201 .type __longdouble_used,@object 202 .size __longdouble_used,4 203 .align 4 204__longdouble_used: 205 .4byte 0x0 206