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 (c) 1988 AT&T
  24  *        All Rights Reserved
  25  *
  26  *
  27  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  28  * Use is subject to license terms.
  29  */
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 /*
  33  * Bootstrap routine for run-time linker.
  34  * We get control from exec which has loaded our text and
  35  * data into the process' address space and created the process
  36  * stack.
  37  *
  38  * On entry, the process stack looks like this:
  39  *
  40  *      #                       # <- %esp
  41  *      #_______________________#  high addresses
  42  *      #       strings         #
  43  *      #_______________________#
  44  *      #       0 word          #
  45  *      #_______________________#
  46  *      #       Auxiliary       #
  47  *      #       entries         #
  48  *      #       ...             #
  49  *      #       (size varies)   #
  50  *      #_______________________#
  51  *      #       0 word          #
  52  *      #_______________________#
  53  *      #       Environment     #
  54  *      #       pointers        #
  55  *      #       ...             #
  56  *      #       (one word each) #
  57  *      #_______________________#
  58  *      #       0 word          #
  59  *      #_______________________#
  60  *      #       Argument        # low addresses
  61  *      #       pointers        #
  62  *      #       Argc words      #
  63  *      #_______________________#
  64  *      #       argc            #
  65  *      #_______________________# <- %ebp
  66  *
  67  *
  68  * We must calculate the address at which ld.so was loaded,
  69  * find the addr of the dynamic section of ld.so, of argv[0], and  of
  70  * the process' environment pointers - and pass the thing to _setup
  71  * to handle.  We then call _rtld - on return we jump to the entry
  72  * point for the a.out.
  73  */
  74 
  75 #if     defined(lint)
  76 
  77 extern  unsigned long   _setup();
  78 extern  void            atexit_fini();
  79 void
  80 main()
  81 {
  82         (void) _setup();
  83         atexit_fini();
  84 }
  85 
  86 #else
  87 
  88 #include        <link.h>
  89 
  90         .file   "boot.s"
  91         .text
  92         .globl  _rt_boot
  93         .globl  _setup
  94         .globl  _GLOBAL_OFFSET_TABLE_
  95         .type   _rt_boot,@function
  96         .align  4
  97 
  98 _rt_alias:
  99         jmp     .get_ip                 / in case we were invoked from libc.so
 100 _rt_boot:
 101         movl    %esp,%ebp               / save for referencing args
 102         subl    $EB_MAX_SIZE32,%esp     / make room for a max sized boot vector
 103         movl    %esp,%esi               / use esi as a pointer to &eb[0]
 104         movl    $EB_ARGV,0(%esi)        / set up tag for argv
 105         leal    4(%ebp),%eax            / get address of argv
 106         movl    %eax,4(%esi)            / put after tag
 107         movl    $EB_ENVP,8(%esi)        / set up tag for envp
 108         movl    (%ebp),%eax             / get # of args
 109         addl    $2,%eax                 / one for the zero & one for argc
 110         leal    (%ebp,%eax,4),%edi      / now points past args & @ envp
 111         movl    %edi,12(%esi)           / set envp
 112 .L0:    addl    $4,%edi                 / next
 113         cmpl    $0,-4(%edi)             / search for 0 at end of env
 114         jne     .L0
 115         movl    $EB_AUXV,16(%esi)       / set up tag for auxv
 116         movl    %edi,20(%esi)           / point to auxv
 117         movl    $EB_NULL,24(%esi)       / set up NULL tag
 118 .get_ip:
 119         call    .L1                     / only way to get IP into a register
 120 .L1:
 121         popl    %ebx                    / pop the IP we just "pushed"
 122         addl    $_GLOBAL_OFFSET_TABLE_+[.-.L1],%ebx
 123         pushl   (%ebx)                  / address of dynamic structure
 124         pushl   %esi                    / push &eb[0]
 125 
 126         call    _setup@PLT              / _setup(&eb[0], _DYNAMIC)
 127         movl    %ebp,%esp               / release stack frame
 128 
 129         movl    atexit_fini@GOT(%ebx), %edx
 130         jmp     *%eax                   / transfer control to a.out
 131         .size   _rt_boot,.-_rt_boot
 132 
 133 #endif