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