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