Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* crt1.s for Solaris 2, x86
  2.  
  3.    Copyright (C) 1993-2015 Free Software Foundation, Inc.
  4.    Written By Fred Fish, Nov 1992
  5.  
  6. This file is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 3, or (at your option) any
  9. later version.
  10.  
  11. This file is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. General Public License for more details.
  15.  
  16. Under Section 7 of GPL version 3, you are granted additional
  17. permissions described in the GCC Runtime Library Exception, version
  18. 3.1, as published by the Free Software Foundation.
  19.  
  20. You should have received a copy of the GNU General Public License and
  21. a copy of the GCC Runtime Library Exception along with this program;
  22. see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. <http://www.gnu.org/licenses/>.  */
  24.  
  25.  
  26. /* This file takes control of the process from the kernel, as specified
  27.    in section 3 of the System V Application Binary Interface, Intel386
  28.    Processor Supplement.  It has been constructed from information obtained
  29.    from the ABI, information obtained from single stepping existing
  30.    Solaris executables through their startup code with gdb, and from
  31.    information obtained by single stepping executables on other i386 SVR4
  32.    implementations.  This file is the first thing linked into any
  33.    executable.  */
  34.  
  35. #ifndef GCRT1
  36.         .ident  "GNU C crt1.s"
  37. #define CLEANUP _cleanup
  38. #else
  39. /* This is a modified crt1.s by J.W.Hawtin <oolon@ankh.org> 15/8/96,
  40.    to allow program profiling, by calling monstartup on entry and _mcleanup
  41.    on exit.  */
  42.         .ident  "GNU C gcrt1.s"
  43. #define CLEANUP _mcleanup
  44. #endif
  45.         .weak   _cleanup
  46.         .weak   _DYNAMIC
  47.         .text
  48.  
  49. /* Start creating the initial frame by pushing a NULL value for the return
  50.    address of the initial frame, and mark the end of the stack frame chain
  51.    (the innermost stack frame) with a NULL value, per page 3-32 of the ABI.
  52.    Initialize the first stack frame pointer in %ebp (the contents of which
  53.    are unspecified at process initialization).  */
  54.  
  55.         .globl  _start
  56. _start:
  57.         pushl   $0x0
  58.         pushl   $0x0
  59.         movl    %esp,%ebp
  60.  
  61. /* As specified per page 3-32 of the ABI, %edx contains a function
  62.    pointer that should be registered with atexit(), for proper
  63.    shared object termination.  Just push it onto the stack for now
  64.    to preserve it.  We want to register _cleanup() first.  */
  65.  
  66.         pushl   %edx
  67.  
  68. /* Check to see if there is an _cleanup() function linked in, and if
  69.    so, register it with atexit() as the last thing to be run by
  70.    atexit().  */
  71.  
  72.         movl    $CLEANUP,%eax
  73.         testl   %eax,%eax
  74.         je      .L1
  75.         pushl   $CLEANUP
  76.         call    atexit
  77.         addl    $0x4,%esp
  78. .L1:
  79.  
  80. /* Now check to see if we have an _DYNAMIC table, and if so then
  81.    we need to register the function pointer previously in %edx, but
  82.    now conveniently saved on the stack as the argument to pass to
  83.    atexit().  */
  84.  
  85.         movl    $_DYNAMIC,%eax
  86.         testl   %eax,%eax
  87.         je      .L2
  88.         call    atexit
  89. .L2:
  90.  
  91. /* Register _fini() with atexit().  We will take care of calling _init()
  92.    directly.  */
  93.  
  94.         pushl   $_fini
  95.         call    atexit
  96.  
  97. #ifdef GCRT1
  98. /* Start profiling.  */
  99.  
  100.         pushl %ebp
  101.         movl %esp,%ebp
  102.         pushl $_etext
  103.         pushl $_start
  104.         call monstartup
  105.         addl $8,%esp
  106.         popl %ebp
  107. #endif
  108.  
  109. /* Compute the address of the environment vector on the stack and load
  110.    it into the global variable _environ.  Currently argc is at 8 off
  111.    the frame pointer.  Fetch the argument count into %eax, scale by the
  112.    size of each arg (4 bytes) and compute the address of the environment
  113.    vector which is 16 bytes (the two zero words we pushed, plus argc,
  114.    plus the null word terminating the arg vector) further up the stack,
  115.    off the frame pointer (whew!).  */
  116.  
  117.         movl    8(%ebp),%eax
  118.         leal    16(%ebp,%eax,4),%edx
  119.         movl    %edx,_environ
  120.  
  121. /* Push the environment vector pointer, the argument vector pointer,
  122.    and the argument count on to the stack to set up the arguments
  123.    for _init(), _fpstart(), and main().  Note that the environment
  124.    vector pointer and the arg count were previously loaded into
  125.    %edx and %eax respectively.  The only new value we need to compute
  126.    is the argument vector pointer, which is at a fixed address off
  127.    the initial frame pointer.  */
  128.  
  129. /* Make sure the stack is properly aligned.  */
  130.         andl $0xfffffff0,%esp
  131.         subl $4,%esp
  132.  
  133.         pushl   %edx
  134.         leal    12(%ebp),%edx
  135.         pushl   %edx
  136.         pushl   %eax
  137.  
  138. /* Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and
  139.    main(argc, argv, environ).  */
  140.  
  141.         call    _init
  142.         call    __fpstart
  143.         call    main
  144.  
  145. /* Pop the argc, argv, and environ arguments off the stack, push the
  146.    value returned from main(), and call exit().  */
  147.  
  148.         addl    $12,%esp
  149.         pushl   %eax
  150.         call    exit
  151.  
  152. /* An inline equivalent of _exit, as specified in Figure 3-26 of the ABI.  */
  153.  
  154.         pushl   $0x0
  155.         movl    $0x1,%eax
  156.         lcall   $7,$0
  157.  
  158. /* If all else fails, just try a halt!  */
  159.  
  160.         hlt
  161.         .type   _start,@function
  162.         .size   _start,.-_start
  163.  
  164. #ifndef GCRT1
  165. /* A dummy profiling support routine for non-profiling executables,
  166.    in case we link in some objects that have been compiled for profiling.  */
  167.  
  168.         .weak   _mcount
  169. _mcount:
  170.         ret
  171.         .type   _mcount,@function
  172.         .size   _mcount,.-_mcount
  173. #endif
  174.